@@ -785,9 +785,14 @@ def __init__(self, elements: Iterable[Any]):
785785 self ._elements = elements
786786
787787 def expand (self , pcoll ):
788+ def to_dict (row ):
789+ # filter None when comparing
790+ temp_dict = {k : v for k , v in row ._asdict ().items () if v is not None }
791+ return dict (temp_dict .items ())
792+
788793 return assert_that (
789- pcoll | beam .Map (lambda row : beam . Row ( ** row . _asdict ()) ),
790- equal_to (dicts_to_rows (self ._elements )))
794+ pcoll | beam .Map (to_dict ),
795+ equal_to ([ to_dict ( e ) for e in dicts_to_rows (self ._elements )] ))
791796
792797 @staticmethod
793798 def create (elements : Iterable [Any ], reshuffle : Optional [bool ] = True ):
@@ -838,7 +843,32 @@ def create(elements: Iterable[Any], reshuffle: Optional[bool] = True):
838843 # not the intent.
839844 if not isinstance (elements , Iterable ) or isinstance (elements , (dict , str )):
840845 raise TypeError ('elements must be a list of elements' )
841- return beam .Create ([element_to_rows (e ) for e in elements ],
846+
847+ # Check if elements have different keys
848+ updated_elements = elements
849+ if elements and all (isinstance (e , dict ) for e in elements ):
850+ keys = [set (e .keys ()) for e in elements ]
851+ if len (set .union (* keys )) > min (len (k ) for k in keys ):
852+ # Merge all dictionaries to get all possible keys
853+ all_keys = set ()
854+ for element in elements :
855+ if isinstance (element , dict ):
856+ all_keys .update (element .keys ())
857+
858+ # Create a merged dictionary with all keys
859+ merged_dict = {}
860+ for key in all_keys :
861+ merged_dict [key ] = None # Use None as a default value
862+
863+ # Update each element with the merged dictionary
864+ updated_elements = []
865+ for e in elements :
866+ if isinstance (e , dict ):
867+ updated_elements .append ({** merged_dict , ** e })
868+ else :
869+ updated_elements .append (e )
870+
871+ return beam .Create ([element_to_rows (e ) for e in updated_elements ],
842872 reshuffle = reshuffle is not False )
843873
844874 # Or should this be posargs, args?
0 commit comments