55import decimal
66from abc import ABC , abstractmethod
77from collections import OrderedDict , namedtuple
8- from collections .abc import Iterable
8+ from collections .abc import Mapping
99from decimal import Decimal
1010from enum import Enum
11- from typing import Any , Dict , List , Optional , Union
11+ from typing import Any , Dict , List , Optional , Union , Sequence
1212import re
1313
1414import lz4 .frame
@@ -458,8 +458,15 @@ def escape_string(self, item):
458458 return "'{}'" .format (item .replace ("\\ " , "\\ \\ " ).replace ("'" , "\\ '" ))
459459
460460 def escape_sequence (self , item ):
461- l = map (str , map (self .escape_item , item ))
462- return "(" + "," .join (l ) + ")"
461+ l = map (self .escape_item , item )
462+ return "ARRAY(" + "," .join (l ) + ")"
463+
464+ def escape_mapping (self , item ):
465+ l = map (
466+ self .escape_item ,
467+ (element for key , value in item .items () for element in (key , value )),
468+ )
469+ return "MAP(" + "," .join (l ) + ")"
463470
464471 def escape_datetime (self , item , format , cutoff = 0 ):
465472 dt_str = item .strftime (format )
@@ -476,14 +483,16 @@ def escape_item(self, item):
476483 return self .escape_number (item )
477484 elif isinstance (item , str ):
478485 return self .escape_string (item )
479- elif isinstance (item , Iterable ):
480- return self .escape_sequence (item )
481486 elif isinstance (item , datetime .datetime ):
482487 return self .escape_datetime (item , self ._DATETIME_FORMAT )
483488 elif isinstance (item , datetime .date ):
484489 return self .escape_datetime (item , self ._DATE_FORMAT )
485490 elif isinstance (item , decimal .Decimal ):
486491 return self .escape_decimal (item )
492+ elif isinstance (item , Sequence ):
493+ return self .escape_sequence (item )
494+ elif isinstance (item , Mapping ):
495+ return self .escape_mapping (item )
487496 else :
488497 raise exc .ProgrammingError ("Unsupported object {}" .format (item ))
489498
0 commit comments