@@ -37,7 +37,7 @@ def _is_sqlalchemy_engine(con):
37
37
try :
38
38
import sqlalchemy
39
39
_SQLALCHEMY_INSTALLED = True
40
-
40
+
41
41
from distutils .version import LooseVersion
42
42
ver = LooseVersion (sqlalchemy .__version__ )
43
43
# For sqlalchemy versions < 0.8.2, the BIGINT type is recognized
@@ -46,7 +46,7 @@ def _is_sqlalchemy_engine(con):
46
46
if ver < '0.8.2' :
47
47
from sqlalchemy import BigInteger
48
48
from sqlalchemy .ext .compiler import compiles
49
-
49
+
50
50
@compiles (BigInteger , 'sqlite' )
51
51
def compile_big_int_sqlite (type_ , compiler , ** kw ):
52
52
return 'INTEGER'
@@ -144,7 +144,7 @@ def _safe_fetch(cur):
144
144
if not isinstance (result , list ):
145
145
result = list (result )
146
146
return result
147
- except Exception as e : # pragma: no cover
147
+ except Exception as e : # pragma: no cover
148
148
excName = e .__class__ .__name__
149
149
if excName == 'OperationalError' :
150
150
return []
@@ -186,7 +186,7 @@ def tquery(sql, con=None, cur=None, retry=True):
186
186
con .commit ()
187
187
except Exception as e :
188
188
excName = e .__class__ .__name__
189
- if excName == 'OperationalError' : # pragma: no cover
189
+ if excName == 'OperationalError' : # pragma: no cover
190
190
print ('Failed to commit, may need to restart interpreter' )
191
191
else :
192
192
raise
@@ -198,7 +198,7 @@ def tquery(sql, con=None, cur=None, retry=True):
198
198
if result and len (result [0 ]) == 1 :
199
199
# python 3 compat
200
200
result = list (lzip (* result )[0 ])
201
- elif result is None : # pragma: no cover
201
+ elif result is None : # pragma: no cover
202
202
result = []
203
203
204
204
return result
@@ -253,7 +253,7 @@ def uquery(sql, con=None, cur=None, retry=True, params=None):
253
253
#--- Read and write to DataFrames
254
254
255
255
def read_sql_table (table_name , con , index_col = None , coerce_float = True ,
256
- parse_dates = None , columns = None ):
256
+ parse_dates = None , columns = None , schema = None ):
257
257
"""Read SQL database table into a DataFrame.
258
258
259
259
Given a table name and an SQLAlchemy engine, returns a DataFrame.
@@ -281,6 +281,7 @@ def read_sql_table(table_name, con, index_col=None, coerce_float=True,
281
281
such as SQLite
282
282
columns : list
283
283
List of column names to select from sql table
284
+ schema : Name of SQL schema in database.
284
285
285
286
Returns
286
287
-------
@@ -299,14 +300,14 @@ def read_sql_table(table_name, con, index_col=None, coerce_float=True,
299
300
from sqlalchemy .schema import MetaData
300
301
meta = MetaData (con )
301
302
try :
302
- meta .reflect (only = [table_name ])
303
+ meta .reflect (only = [table_name ], schema = schema )
303
304
except sqlalchemy .exc .InvalidRequestError :
304
305
raise ValueError ("Table %s not found" % table_name )
305
306
306
307
pandas_sql = PandasSQLAlchemy (con , meta = meta )
307
308
table = pandas_sql .read_table (
308
309
table_name , index_col = index_col , coerce_float = coerce_float ,
309
- parse_dates = parse_dates , columns = columns )
310
+ parse_dates = parse_dates , columns = columns , schema = schema )
310
311
311
312
if table is not None :
312
313
return table
@@ -432,7 +433,7 @@ def read_sql(sql, con, index_col=None, coerce_float=True, params=None,
432
433
433
434
434
435
def to_sql (frame , name , con , flavor = 'sqlite' , if_exists = 'fail' , index = True ,
435
- index_label = None ):
436
+ index_label = None , schema = None ):
436
437
"""
437
438
Write records stored in a DataFrame to a SQL database.
438
439
@@ -459,6 +460,7 @@ def to_sql(frame, name, con, flavor='sqlite', if_exists='fail', index=True,
459
460
Column label for index column(s). If None is given (default) and
460
461
`index` is True, then the index names are used.
461
462
A sequence should be given if the DataFrame uses MultiIndex.
463
+ schema : Name of SQL schema in database.
462
464
463
465
"""
464
466
if if_exists not in ('fail' , 'replace' , 'append' ):
@@ -472,10 +474,10 @@ def to_sql(frame, name, con, flavor='sqlite', if_exists='fail', index=True,
472
474
raise NotImplementedError
473
475
474
476
pandas_sql .to_sql (frame , name , if_exists = if_exists , index = index ,
475
- index_label = index_label )
477
+ index_label = index_label , schema = schema )
476
478
477
479
478
- def has_table (table_name , con , flavor = 'sqlite' ):
480
+ def has_table (table_name , con , flavor = 'sqlite' , schema = None ):
479
481
"""
480
482
Check if DataBase has named table.
481
483
@@ -491,13 +493,14 @@ def has_table(table_name, con, flavor='sqlite'):
491
493
The flavor of SQL to use. Ignored when using SQLAlchemy engine.
492
494
'mysql' is deprecated and will be removed in future versions, but it
493
495
will be further supported through SQLAlchemy engines.
496
+ schema : Name of SQL schema in database.
494
497
495
498
Returns
496
499
-------
497
500
boolean
498
501
"""
499
502
pandas_sql = pandasSQL_builder (con , flavor = flavor )
500
- return pandas_sql .has_table (table_name )
503
+ return pandas_sql .has_table (table_name , schema = schema )
501
504
502
505
table_exists = has_table
503
506
@@ -531,24 +534,26 @@ class PandasSQLTable(PandasObject):
531
534
"""
532
535
# TODO: support for multiIndex
533
536
def __init__ (self , name , pandas_sql_engine , frame = None , index = True ,
534
- if_exists = 'fail' , prefix = 'pandas' , index_label = None ):
537
+ if_exists = 'fail' , prefix = 'pandas' , index_label = None ,
538
+ schema = None ):
535
539
self .name = name
536
540
self .pd_sql = pandas_sql_engine
537
541
self .prefix = prefix
538
542
self .frame = frame
539
543
self .index = self ._index_name (index , index_label )
544
+ self .schema = schema
540
545
541
546
if frame is not None :
542
547
# We want to write a frame
543
- if self .pd_sql .has_table (self .name ):
548
+ if self .pd_sql .has_table (self .name , self . schema ):
544
549
if if_exists == 'fail' :
545
550
raise ValueError ("Table '%s' already exists." % name )
546
551
elif if_exists == 'replace' :
547
- self .pd_sql .drop_table (self .name )
552
+ self .pd_sql .drop_table (self .name , self . schema )
548
553
self .table = self ._create_table_statement ()
549
554
self .create ()
550
555
elif if_exists == 'append' :
551
- self .table = self .pd_sql .get_table (self .name )
556
+ self .table = self .pd_sql .get_table (self .name , self . schema )
552
557
if self .table is None :
553
558
self .table = self ._create_table_statement ()
554
559
else :
@@ -559,13 +564,13 @@ def __init__(self, name, pandas_sql_engine, frame=None, index=True,
559
564
self .create ()
560
565
else :
561
566
# no data provided, read-only mode
562
- self .table = self .pd_sql .get_table (self .name )
567
+ self .table = self .pd_sql .get_table (self .name , self . schema )
563
568
564
569
if self .table is None :
565
570
raise ValueError ("Could not init table '%s'" % name )
566
571
567
572
def exists (self ):
568
- return self .pd_sql .has_table (self .name )
573
+ return self .pd_sql .has_table (self .name , self . schema )
569
574
570
575
def sql_schema (self ):
571
576
from sqlalchemy .schema import CreateTable
@@ -679,7 +684,7 @@ def _create_table_statement(self):
679
684
self .frame .index .get_level_values (i ))
680
685
columns .insert (0 , Column (idx_label , idx_type , index = True ))
681
686
682
- return Table (self .name , self .pd_sql .meta , * columns )
687
+ return Table (self .name , self .pd_sql .meta , * columns , schema = self . schema )
683
688
684
689
def _harmonize_columns (self , parse_dates = None ):
685
690
""" Make a data_frame's column type align with an sql_table
@@ -810,9 +815,10 @@ def execute(self, *args, **kwargs):
810
815
return self .engine .execute (* args , ** kwargs )
811
816
812
817
def read_table (self , table_name , index_col = None , coerce_float = True ,
813
- parse_dates = None , columns = None ):
818
+ parse_dates = None , columns = None , schema = None ):
814
819
815
- table = PandasSQLTable (table_name , self , index = index_col )
820
+ table = PandasSQLTable (
821
+ table_name , self , index = index_col , schema = schema )
816
822
return table .read (coerce_float = coerce_float ,
817
823
parse_dates = parse_dates , columns = columns )
818
824
@@ -835,26 +841,29 @@ def read_sql(self, sql, index_col=None, coerce_float=True,
835
841
return data_frame
836
842
837
843
def to_sql (self , frame , name , if_exists = 'fail' , index = True ,
838
- index_label = None ):
844
+ index_label = None , schema = None ):
839
845
table = PandasSQLTable (
840
846
name , self , frame = frame , index = index , if_exists = if_exists ,
841
- index_label = index_label )
847
+ index_label = index_label , schema = schema )
842
848
table .insert ()
843
849
844
850
@property
845
851
def tables (self ):
846
852
return self .meta .tables
847
853
848
- def has_table (self , name ):
849
- return self .engine .has_table (name )
854
+ def has_table (self , name , schema = None ):
855
+ return self .engine .has_table (name , schema )
850
856
851
- def get_table (self , table_name ):
852
- return self .meta .tables .get (table_name )
857
+ def get_table (self , table_name , schema = None ):
858
+ if schema :
859
+ return self .meta .tables .get ('.' .join ([schema , table_name ]))
860
+ else :
861
+ return self .meta .tables .get (table_name )
853
862
854
- def drop_table (self , table_name ):
855
- if self .engine .has_table (table_name ):
856
- self .meta .reflect (only = [table_name ])
857
- self .get_table (table_name ).drop ()
863
+ def drop_table (self , table_name , schema = None ):
864
+ if self .engine .has_table (table_name , schema ):
865
+ self .meta .reflect (only = [table_name ], schema = schema )
866
+ self .get_table (table_name , schema ).drop ()
858
867
self .meta .clear ()
859
868
860
869
def _create_sql_schema (self , frame , table_name ):
0 commit comments