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):
458458return "'{}'" .format (item .replace ("\\ " ,"\\ \\ " ).replace ("'" ,"\\ '" ))
459459
460460def 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
464471def escape_datetime (self ,item ,format ,cutoff = 0 ):
465472dt_str = item .strftime (format )
@@ -476,14 +483,16 @@ def escape_item(self, item):
476483return self .escape_number (item )
477484elif isinstance (item ,str ):
478485return self .escape_string (item )
479- elif isinstance (item ,Iterable ):
480- return self .escape_sequence (item )
481486elif isinstance (item ,datetime .datetime ):
482487return self .escape_datetime (item ,self ._DATETIME_FORMAT )
483488elif isinstance (item ,datetime .date ):
484489return self .escape_datetime (item ,self ._DATE_FORMAT )
485490elif isinstance (item ,decimal .Decimal ):
486491return 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 )
487496else :
488497raise exc .ProgrammingError ("Unsupported object {}" .format (item ))
489498