@@ -38,7 +38,7 @@ def _is_sqlalchemy_engine(con):
3838 try :
3939 import sqlalchemy
4040 _SQLALCHEMY_INSTALLED = True
41-
41+
4242 from distutils .version import LooseVersion
4343 ver = LooseVersion (sqlalchemy .__version__ )
4444 # For sqlalchemy versions < 0.8.2, the BIGINT type is recognized
@@ -47,7 +47,7 @@ def _is_sqlalchemy_engine(con):
4747 if ver < '0.8.2' :
4848 from sqlalchemy import BigInteger
4949 from sqlalchemy .ext .compiler import compiles
50-
50+
5151 @compiles (BigInteger , 'sqlite' )
5252 def compile_big_int_sqlite (type_ , compiler , ** kw ):
5353 return 'INTEGER'
@@ -145,7 +145,7 @@ def _safe_fetch(cur):
145145 if not isinstance (result , list ):
146146 result = list (result )
147147 return result
148- except Exception as e : # pragma: no cover
148+ except Exception as e : # pragma: no cover
149149 excName = e .__class__ .__name__
150150 if excName == 'OperationalError' :
151151 return []
@@ -187,7 +187,7 @@ def tquery(sql, con=None, cur=None, retry=True):
187187 con .commit ()
188188 except Exception as e :
189189 excName = e .__class__ .__name__
190- if excName == 'OperationalError' : # pragma: no cover
190+ if excName == 'OperationalError' : # pragma: no cover
191191 print ('Failed to commit, may need to restart interpreter' )
192192 else :
193193 raise
@@ -199,7 +199,7 @@ def tquery(sql, con=None, cur=None, retry=True):
199199 if result and len (result [0 ]) == 1 :
200200 # python 3 compat
201201 result = list (lzip (* result )[0 ])
202- elif result is None : # pragma: no cover
202+ elif result is None : # pragma: no cover
203203 result = []
204204
205205 return result
@@ -253,7 +253,7 @@ def uquery(sql, con=None, cur=None, retry=True, params=None):
253253#------------------------------------------------------------------------------
254254#--- Read and write to DataFrames
255255
256- def read_sql_table (table_name , con , index_col = None , coerce_float = True ,
256+ def read_sql_table (table_name , con , schema = None , index_col = None , coerce_float = True ,
257257 parse_dates = None , columns = None ):
258258 """Read SQL database table into a DataFrame.
259259
@@ -266,6 +266,7 @@ def read_sql_table(table_name, con, index_col=None, coerce_float=True,
266266 Name of SQL table in database
267267 con : SQLAlchemy engine
268268 Sqlite DBAPI connection mode not supported
269+ schema : Name of SQL schema in database.
269270 index_col : string, optional
270271 Column to set as index
271272 coerce_float : boolean, default True
@@ -300,14 +301,14 @@ def read_sql_table(table_name, con, index_col=None, coerce_float=True,
300301 from sqlalchemy .schema import MetaData
301302 meta = MetaData (con )
302303 try :
303- meta .reflect (only = [table_name ])
304+ meta .reflect (only = [table_name ], schema = schema )
304305 except sqlalchemy .exc .InvalidRequestError :
305306 raise ValueError ("Table %s not found" % table_name )
306307
307308 pandas_sql = PandasSQLAlchemy (con , meta = meta )
308309 table = pandas_sql .read_table (
309310 table_name , index_col = index_col , coerce_float = coerce_float ,
310- parse_dates = parse_dates , columns = columns )
311+ parse_dates = parse_dates , columns = columns , schema = schema )
311312
312313 if table is not None :
313314 return table
@@ -437,8 +438,8 @@ def read_sql(sql, con, index_col=None, coerce_float=True, params=None,
437438 coerce_float = coerce_float , parse_dates = parse_dates )
438439
439440
440- def to_sql (frame , name , con , flavor = 'sqlite' , if_exists = 'fail' , index = True ,
441- index_label = None , chunksize = None ):
441+ def to_sql (frame , name , con , flavor = 'sqlite' , schema = None , if_exists = 'fail' ,
442+ index = True , index_label = None , chunksize = None ):
442443 """
443444 Write records stored in a DataFrame to a SQL database.
444445
@@ -455,6 +456,7 @@ def to_sql(frame, name, con, flavor='sqlite', if_exists='fail', index=True,
455456 The flavor of SQL to use. Ignored when using SQLAlchemy engine.
456457 'mysql' is deprecated and will be removed in future versions, but it
457458 will be further supported through SQLAlchemy engines.
459+ schema : Name of SQL schema in database.
458460 if_exists : {'fail', 'replace', 'append'}, default 'fail'
459461 - fail: If table exists, do nothing.
460462 - replace: If table exists, drop it, recreate it, and insert data.
@@ -481,10 +483,11 @@ def to_sql(frame, name, con, flavor='sqlite', if_exists='fail', index=True,
481483 raise NotImplementedError
482484
483485 pandas_sql .to_sql (frame , name , if_exists = if_exists , index = index ,
484- index_label = index_label , chunksize = chunksize )
486+ index_label = index_label , schema = schema ,
487+ chunksize = chunksize )
485488
486489
487- def has_table (table_name , con , flavor = 'sqlite' ):
490+ def has_table (table_name , con , flavor = 'sqlite' , schema = None ):
488491 """
489492 Check if DataBase has named table.
490493
@@ -500,13 +503,14 @@ def has_table(table_name, con, flavor='sqlite'):
500503 The flavor of SQL to use. Ignored when using SQLAlchemy engine.
501504 'mysql' is deprecated and will be removed in future versions, but it
502505 will be further supported through SQLAlchemy engines.
506+ schema : Name of SQL schema in database.
503507
504508 Returns
505509 -------
506510 boolean
507511 """
508512 pandas_sql = pandasSQL_builder (con , flavor = flavor )
509- return pandas_sql .has_table (table_name )
513+ return pandas_sql .has_table (table_name , schema = schema )
510514
511515table_exists = has_table
512516
@@ -540,24 +544,26 @@ class PandasSQLTable(PandasObject):
540544 """
541545 # TODO: support for multiIndex
542546 def __init__ (self , name , pandas_sql_engine , frame = None , index = True ,
543- if_exists = 'fail' , prefix = 'pandas' , index_label = None ):
547+ if_exists = 'fail' , prefix = 'pandas' , index_label = None ,
548+ schema = None ):
544549 self .name = name
545550 self .pd_sql = pandas_sql_engine
546551 self .prefix = prefix
547552 self .frame = frame
548553 self .index = self ._index_name (index , index_label )
554+ self .schema = schema
549555
550556 if frame is not None :
551557 # We want to write a frame
552- if self .pd_sql .has_table (self .name ):
558+ if self .pd_sql .has_table (self .name , self . schema ):
553559 if if_exists == 'fail' :
554560 raise ValueError ("Table '%s' already exists." % name )
555561 elif if_exists == 'replace' :
556- self .pd_sql .drop_table (self .name )
562+ self .pd_sql .drop_table (self .name , self . schema )
557563 self .table = self ._create_table_statement ()
558564 self .create ()
559565 elif if_exists == 'append' :
560- self .table = self .pd_sql .get_table (self .name )
566+ self .table = self .pd_sql .get_table (self .name , self . schema )
561567 if self .table is None :
562568 self .table = self ._create_table_statement ()
563569 else :
@@ -568,13 +574,13 @@ def __init__(self, name, pandas_sql_engine, frame=None, index=True,
568574 self .create ()
569575 else :
570576 # no data provided, read-only mode
571- self .table = self .pd_sql .get_table (self .name )
577+ self .table = self .pd_sql .get_table (self .name , self . schema )
572578
573579 if self .table is None :
574580 raise ValueError ("Could not init table '%s'" % name )
575581
576582 def exists (self ):
577- return self .pd_sql .has_table (self .name )
583+ return self .pd_sql .has_table (self .name , self . schema )
578584
579585 def sql_schema (self ):
580586 from sqlalchemy .schema import CreateTable
@@ -709,7 +715,7 @@ def _create_table_statement(self):
709715 columns = [Column (name , typ )
710716 for name , typ in column_names_and_types ]
711717
712- return Table (self .name , self .pd_sql .meta , * columns )
718+ return Table (self .name , self .pd_sql .meta , * columns , schema = self . schema )
713719
714720 def _harmonize_columns (self , parse_dates = None ):
715721 """ Make a data_frame's column type align with an sql_table
@@ -843,9 +849,10 @@ def execute(self, *args, **kwargs):
843849 return self .engine .execute (* args , ** kwargs )
844850
845851 def read_table (self , table_name , index_col = None , coerce_float = True ,
846- parse_dates = None , columns = None ):
852+ parse_dates = None , columns = None , schema = None ):
847853
848- table = PandasSQLTable (table_name , self , index = index_col )
854+ table = PandasSQLTable (
855+ table_name , self , index = index_col , schema = schema )
849856 return table .read (coerce_float = coerce_float ,
850857 parse_dates = parse_dates , columns = columns )
851858
@@ -868,26 +875,29 @@ def read_sql(self, sql, index_col=None, coerce_float=True,
868875 return data_frame
869876
870877 def to_sql (self , frame , name , if_exists = 'fail' , index = True ,
871- index_label = None , chunksize = None ):
878+ index_label = None , schema = None , chunksize = None ):
872879 table = PandasSQLTable (
873880 name , self , frame = frame , index = index , if_exists = if_exists ,
874- index_label = index_label )
881+ index_label = index_label , schema = schema )
875882 table .insert (chunksize )
876883
877884 @property
878885 def tables (self ):
879886 return self .meta .tables
880887
881- def has_table (self , name ):
882- return self .engine .has_table (name )
888+ def has_table (self , name , schema = None ):
889+ return self .engine .has_table (name , schema )
883890
884- def get_table (self , table_name ):
885- return self .meta .tables .get (table_name )
891+ def get_table (self , table_name , schema = None ):
892+ if schema :
893+ return self .meta .tables .get ('.' .join ([schema , table_name ]))
894+ else :
895+ return self .meta .tables .get (table_name )
886896
887- def drop_table (self , table_name ):
888- if self .engine .has_table (table_name ):
889- self .meta .reflect (only = [table_name ])
890- self .get_table (table_name ).drop ()
897+ def drop_table (self , table_name , schema = None ):
898+ if self .engine .has_table (table_name , schema ):
899+ self .meta .reflect (only = [table_name ], schema = schema )
900+ self .get_table (table_name , schema ).drop ()
891901 self .meta .clear ()
892902
893903 def _create_sql_schema (self , frame , table_name ):
0 commit comments