@@ -566,17 +566,17 @@ def __init__(self, name, pandas_sql_engine, frame=None, index=True,
566
566
raise ValueError ("Table '%s' already exists." % name )
567
567
elif if_exists == 'replace' :
568
568
self .pd_sql .drop_table (self .name , self .schema )
569
- self .table = self ._create_table_statement ()
569
+ self .table = self ._create_table_setup ()
570
570
self .create ()
571
571
elif if_exists == 'append' :
572
572
self .table = self .pd_sql .get_table (self .name , self .schema )
573
573
if self .table is None :
574
- self .table = self ._create_table_statement ()
574
+ self .table = self ._create_table_setup ()
575
575
else :
576
576
raise ValueError (
577
577
"'{0}' is not valid for if_exists" .format (if_exists ))
578
578
else :
579
- self .table = self ._create_table_statement ()
579
+ self .table = self ._create_table_setup ()
580
580
self .create ()
581
581
else :
582
582
# no data provided, read-only mode
@@ -703,23 +703,25 @@ def _get_column_names_and_types(self, dtype_mapper):
703
703
for i , idx_label in enumerate (self .index ):
704
704
idx_type = dtype_mapper (
705
705
self .frame .index .get_level_values (i ))
706
- column_names_and_types .append ((idx_label , idx_type ))
706
+ column_names_and_types .append ((idx_label , idx_type , True ))
707
707
708
708
column_names_and_types += [
709
709
(str (self .frame .columns [i ]),
710
- dtype_mapper (self .frame .iloc [:,i ]))
710
+ dtype_mapper (self .frame .iloc [:,i ]),
711
+ False )
711
712
for i in range (len (self .frame .columns ))
712
713
]
714
+
713
715
return column_names_and_types
714
716
715
- def _create_table_statement (self ):
717
+ def _create_table_setup (self ):
716
718
from sqlalchemy import Table , Column
717
719
718
720
column_names_and_types = \
719
721
self ._get_column_names_and_types (self ._sqlalchemy_type )
720
722
721
- columns = [Column (name , typ )
722
- for name , typ in column_names_and_types ]
723
+ columns = [Column (name , typ , index = is_index )
724
+ for name , typ , is_index in column_names_and_types ]
723
725
724
726
return Table (self .name , self .pd_sql .meta , * columns , schema = self .schema )
725
727
@@ -979,10 +981,12 @@ class PandasSQLTableLegacy(PandasSQLTable):
979
981
Instead of a table variable just use the Create Table
980
982
statement"""
981
983
def sql_schema (self ):
982
- return str (self .table )
984
+ return str ("; \n " . join ( self .table ) )
983
985
984
986
def create (self ):
985
- self .pd_sql .execute (self .table )
987
+ with self .pd_sql .con :
988
+ for stmt in self .table :
989
+ self .pd_sql .execute (stmt )
986
990
987
991
def insert_statement (self ):
988
992
names = list (map (str , self .frame .columns ))
@@ -1026,14 +1030,17 @@ def insert(self, chunksize=None):
1026
1030
cur .executemany (ins , data_list )
1027
1031
cur .close ()
1028
1032
1029
- def _create_table_statement (self ):
1030
- "Return a CREATE TABLE statement to suit the contents of a DataFrame."
1033
+ def _create_table_setup (self ):
1034
+ """Return a list of SQL statement that create a table reflecting the
1035
+ structure of a DataFrame. The first entry will be a CREATE TABLE
1036
+ statement while the rest will be CREATE INDEX statements
1037
+ """
1031
1038
1032
1039
column_names_and_types = \
1033
1040
self ._get_column_names_and_types (self ._sql_type_name )
1034
1041
1035
1042
pat = re .compile ('\s+' )
1036
- column_names = [col_name for col_name , _ in column_names_and_types ]
1043
+ column_names = [col_name for col_name , _ , _ in column_names_and_types ]
1037
1044
if any (map (pat .search , column_names )):
1038
1045
warnings .warn (_SAFE_NAMES_WARNING )
1039
1046
@@ -1044,13 +1051,21 @@ def _create_table_statement(self):
1044
1051
1045
1052
col_template = br_l + '%s' + br_r + ' %s'
1046
1053
1047
- columns = ',\n ' .join (col_template %
1048
- x for x in column_names_and_types )
1054
+ columns = ',\n ' .join (col_template % ( cname , ctype )
1055
+ for cname , ctype , _ in column_names_and_types )
1049
1056
template = """CREATE TABLE %(name)s (
1050
1057
%(columns)s
1051
1058
)"""
1052
- create_statement = template % {'name' : self .name , 'columns' : columns }
1053
- return create_statement
1059
+ create_stmts = [template % {'name' : self .name , 'columns' : columns }, ]
1060
+
1061
+ ix_tpl = "CREATE INDEX ix_{tbl}_{col} ON {tbl} ({br_l}{col}{br_r})"
1062
+ for cname , _ , is_index in column_names_and_types :
1063
+ if not is_index :
1064
+ continue
1065
+ create_stmts .append (ix_tpl .format (tbl = self .name , col = cname ,
1066
+ br_l = br_l , br_r = br_r ))
1067
+
1068
+ return create_stmts
1054
1069
1055
1070
def _sql_type_name (self , col ):
1056
1071
pytype = col .dtype .type
0 commit comments