@@ -367,11 +367,13 @@ async def _upsert_multiple(
367367 f"alternate_keys and records must have the same length " f"({ len (alternate_keys )} != { len (records )} )"
368368 )
369369 logical_name = table_schema_name .lower ()
370+ lowered_records = [self ._lowercase_keys (r ) for r in records ]
371+ converted = await asyncio .gather (* [
372+ self ._convert_labels_to_ints (table_schema_name , r ) for r in lowered_records
373+ ])
370374 targets : List [Dict [str , Any ]] = []
371- for alt_key , record in zip (alternate_keys , records ):
375+ for alt_key , record_processed in zip (alternate_keys , converted ):
372376 alt_key_lower = self ._lowercase_keys (alt_key )
373- record_processed = self ._lowercase_keys (record )
374- record_processed = await self ._convert_labels_to_ints (table_schema_name , record_processed )
375377 conflicting = {
376378 k for k in set (alt_key_lower ) & set (record_processed ) if alt_key_lower [k ] != record_processed [k ]
377379 }
@@ -429,7 +431,7 @@ async def _update_by_ids(
429431 if isinstance (changes , dict ):
430432 batch = [{pk_attr : rid , ** changes } for rid in ids ]
431433 await self ._update_multiple (entity_set , table_schema_name , batch )
432- return None
434+ return
433435 if not isinstance (changes , list ):
434436 raise TypeError ("changes must be dict or list[dict]" )
435437 if len (changes ) != len (ids ):
@@ -440,7 +442,6 @@ async def _update_by_ids(
440442 raise TypeError ("Each patch must be a dict" )
441443 batch .append ({pk_attr : rid , ** patch })
442444 await self ._update_multiple (entity_set , table_schema_name , batch )
443- return None
444445
445446 async def _delete_multiple (
446447 self ,
@@ -513,7 +514,6 @@ async def _update_multiple(
513514 if not isinstance (records , list ) or not records or not all (isinstance (r , dict ) for r in records ):
514515 raise TypeError ("records must be a non-empty list[dict]" )
515516 await self ._execute_raw (await self ._build_update_multiple_from_records (entity_set , table_schema_name , records ))
516- return None
517517
518518 async def _delete (self , table_schema_name : str , key : str ) -> None :
519519 """Delete a record by GUID.
@@ -1477,10 +1477,11 @@ async def _delete_columns(
14771477 deleted : List [str ] = []
14781478 needs_picklist_flush = False
14791479
1480- for column_name in names :
1481- attr_meta = await self ._get_attribute_metadata (
1482- metadata_id , column_name , extra_select = "@odata.type,AttributeType"
1483- )
1480+ attr_metas = await asyncio .gather (* [
1481+ self ._get_attribute_metadata (metadata_id , col , extra_select = "@odata.type,AttributeType" )
1482+ for col in names
1483+ ])
1484+ for column_name , attr_meta in zip (names , attr_metas ):
14841485 if not attr_meta :
14851486 raise MetadataError (
14861487 f"Column '{ column_name } ' not found on table '{ entity_schema } '." ,
@@ -1536,13 +1537,12 @@ async def _build_create_multiple(
15361537 if not all (isinstance (r , dict ) for r in records ):
15371538 raise TypeError ("All items for multi-create must be dicts" )
15381539 logical_name = table .lower ()
1539- enriched = []
1540- for r in records :
1541- r = self ._lowercase_keys (r )
1542- r = await self ._convert_labels_to_ints (table , r )
1543- if "@odata.type" not in r :
1544- r = {** r , "@odata.type" : f"Microsoft.Dynamics.CRM.{ logical_name } " }
1545- enriched .append (r )
1540+ lowered = [self ._lowercase_keys (r ) for r in records ]
1541+ converted = await asyncio .gather (* [self ._convert_labels_to_ints (table , r ) for r in lowered ])
1542+ enriched = [
1543+ {** r , "@odata.type" : f"Microsoft.Dynamics.CRM.{ logical_name } " } if "@odata.type" not in r else r
1544+ for r in converted
1545+ ]
15461546 return _RawRequest (
15471547 method = "POST" ,
15481548 url = f"{ self .api } /{ entity_set } /Microsoft.Dynamics.CRM.CreateMultiple" ,
@@ -1590,13 +1590,12 @@ async def _build_update_multiple_from_records(
15901590 :meth:`_build_update_multiple` (which assembles from ids + changes).
15911591 """
15921592 logical_name = table .lower ()
1593- enriched = []
1594- for r in records :
1595- r = self ._lowercase_keys (r )
1596- r = await self ._convert_labels_to_ints (table , r )
1597- if "@odata.type" not in r :
1598- r = {** r , "@odata.type" : f"Microsoft.Dynamics.CRM.{ logical_name } " }
1599- enriched .append (r )
1593+ lowered = [self ._lowercase_keys (r ) for r in records ]
1594+ converted = await asyncio .gather (* [self ._convert_labels_to_ints (table , r ) for r in lowered ])
1595+ enriched = [
1596+ {** r , "@odata.type" : f"Microsoft.Dynamics.CRM.{ logical_name } " } if "@odata.type" not in r else r
1597+ for r in converted
1598+ ]
16001599 return _RawRequest (
16011600 method = "POST" ,
16021601 url = f"{ self .api } /{ entity_set } /Microsoft.Dynamics.CRM.UpdateMultiple" ,
@@ -1661,11 +1660,11 @@ async def _build_upsert_multiple(
16611660 subcode = "upsert_length_mismatch" ,
16621661 )
16631662 logical_name = table .lower ()
1663+ lowered_records = [self ._lowercase_keys (r ) for r in records ]
1664+ converted = await asyncio .gather (* [self ._convert_labels_to_ints (table , r ) for r in lowered_records ])
16641665 targets : List [Dict [str , Any ]] = []
1665- for alt_key , record in zip (alternate_keys , records ):
1666+ for alt_key , record_processed in zip (alternate_keys , converted ):
16661667 alt_key_lower = self ._lowercase_keys (alt_key )
1667- record_processed = self ._lowercase_keys (record )
1668- record_processed = await self ._convert_labels_to_ints (table , record_processed )
16691668 conflicting = {
16701669 k for k in set (alt_key_lower ) & set (record_processed ) if alt_key_lower [k ] != record_processed [k ]
16711670 }
0 commit comments