1313
1414from odps import ODPS , tunnel
1515from runtime .dbapi .connection import Connection , ResultSet
16+ from six .moves .urllib .parse import parse_qs , urlparse
17+
18+ COMPRESS_ODPS_ZLIB = tunnel .CompressOption .CompressAlgorithm .ODPS_ZLIB
1619
1720
1821class MaxComputeResultSet (ResultSet ):
1922 """MaxCompute query result"""
2023 def __init__ (self , instance , err = None ):
21- super ().__init__ ()
24+ super (MaxComputeResultSet , self ).__init__ ()
2225 self ._instance = instance
2326 self ._column_info = None
2427 self ._err = err
@@ -40,18 +43,17 @@ def column_info(self):
4043 A list of column metas, like [(field_a, INT), (field_b, STRING)]
4144 """
4245 if self ._column_info is not None :
43- return self .column_info
46+ return self ._column_info
4447
4548 r = self ._open_reader ()
46- self ._column_info = [(col .name , str . upper (col .type ))
49+ self ._column_info = [(col .name , str (col .type ). upper ( ))
4750 for col in r ._schema .columns ]
4851 return self ._column_info
4952
5053 def _open_reader (self ):
5154 if not self ._reader :
52- compress = tunnel .CompressOption .CompressAlgorithm .ODPS_ZLIB
53- self ._reader = self ._instance .open_reader (tunnel = True ,
54- compress_option = compress )
55+ self ._reader = self ._instance .open_reader (
56+ tunnel = True , compress_option = COMPRESS_ODPS_ZLIB )
5557 return self ._reader
5658
5759 def success (self ):
@@ -81,18 +83,33 @@ class MaxComputeConnection(Connection):
8183 maxcompute://access_id:access_key@service.com/api?curr_project=test_ci&scheme=http
8284 """
8385 def __init__ (self , conn_uri ):
84- super ().__init__ (conn_uri )
86+ super (MaxComputeConnection , self ).__init__ (conn_uri )
87+ user , pwd , endpoint , proj = MaxComputeConnection .get_uri_parts (
88+ conn_uri )
8589 self .driver = "maxcompute"
86- self .params ["database" ] = self .params ["curr_project" ]
90+ self .params ["database" ] = proj
91+ self .endpoint = endpoint
92+ self ._conn = ODPS (user , pwd , project = proj , endpoint = endpoint )
93+
94+ @staticmethod
95+ def get_uri_parts (uri ):
96+ """Get username, password, endpoint, projectfrom given uri
97+
98+ Args:
99+ uri: a vliad maxcompute connection uri
100+
101+ Returns:
102+ A tuple (username, password, endpoint, project)
103+ """
104+ uripts = urlparse (uri )
105+ params = parse_qs (uripts .query )
87106 # compose an endpoint, only keep the host and path and replace scheme
88- endpoint = self .uripts ._replace (scheme = self .params ["scheme" ],
89- query = "" ,
90- netloc = self .uripts .hostname )
91- self .endpoint = endpoint .geturl ()
92- self ._conn = ODPS (self .uripts .username ,
93- self .uripts .password ,
94- project = self .params ["database" ],
95- endpoint = self .endpoint )
107+ endpoint = uripts ._replace (scheme = params .get ("scheme" , ["http" ])[0 ],
108+ query = "" ,
109+ netloc = uripts .hostname )
110+ endpoint = endpoint .geturl ()
111+ return (uripts .username , uripts .password , endpoint ,
112+ params .get ("curr_project" , ["" ])[0 ])
96113
97114 def _get_result_set (self , statement ):
98115 try :
@@ -108,3 +125,19 @@ def close(self):
108125 def get_table_schema (self , table_name ):
109126 schema = self ._conn .get_table (table_name ).schema
110127 return [(c .name , str (c .type ).upper ()) for c in schema .columns ]
128+
129+ def write_table (self ,
130+ table_name ,
131+ rows ,
132+ compress_option = COMPRESS_ODPS_ZLIB ):
133+ """Append rows to given table, this is a driver specific api
134+
135+ Args:
136+ table_name: the table to write
137+ rows: list of rows, each row is a data tuple, like [(1,True,"ok"),(2,False,"bad")]
138+ compress_options: the compress options defined in
139+ tunnel.CompressOption.CompressAlgorithm
140+ """
141+ self ._conn .write_table (table_name ,
142+ rows ,
143+ compress_option = compress_option )
0 commit comments