Skip to content

BUG/ENH: to_sql fails to detect tables via if_exists on mysql with capitalised table names #7815

Closed
@maxgrenderjones

Description

@maxgrenderjones

Demonstration code, running on windows (so case insensitive) with pandas 0.14.0

engine=create_engine('mysql://{username}:{password}@{host}/{database}?charset=utf8'.format(**db))
metadata=MetaData(bind=engine)
table=Table('foo', metadata, Column('id', Integer, primary_key=True), Column('language', Unicode(255)), Column('animal', Unicode(255)))
data=DataFrame.from_dict({1: {'language': 'python', 'animal': 'snake'}, 2: {'language': 'perl', 'animal': 'camel'}}, orient='index')
data.to_sql('Foo', engine, if_exists='replace')
data.to_sql('Foo', engine, if_exists='replace')

Fails with:

OperationalError                          Traceback (most recent call last)
<ipython-input-48-9d53c43e59f6> in <module>()
      1 data.to_sql('Foo', engine, if_exists='replace')
----> 2 data.to_sql('Foo', engine, if_exists='replace')

C:\Anaconda\lib\site-packages\pandas\core\generic.pyc in to_sql(self, name, con, flavor, if_exists, index, index_label)
    948         sql.to_sql(
    949             self, name, con, flavor=flavor, if_exists=if_exists, index=index,
--> 950             index_label=index_label)
    951 
    952     def to_pickle(self, path):

C:\Anaconda\lib\site-packages\pandas\io\sql.pyc in to_sql(frame, name, con, flavor, if_exists, index, index_label)
    438 
    439     pandas_sql.to_sql(frame, name, if_exists=if_exists, index=index,
--> 440                       index_label=index_label)
    441 
    442 

C:\Anaconda\lib\site-packages\pandas\io\sql.pyc in to_sql(self, frame, name, if_exists, index, index_label)
    812         table = PandasSQLTable(
    813             name, self, frame=frame, index=index, if_exists=if_exists,
--> 814             index_label=index_label)
    815         table.insert()
    816 

C:\Anaconda\lib\site-packages\pandas\io\sql.pyc in __init__(self, name, pandas_sql_engine, frame, index, if_exists, prefix, index_label)
    530             else:
    531                 self.table = self._create_table_statement()
--> 532                 self.create()
    533         else:
    534             # no data provided, read-only mode

C:\Anaconda\lib\site-packages\pandas\io\sql.pyc in create(self)
    546 
    547     def create(self):
--> 548         self.table.create()
    549 
    550     def insert_statement(self):

C:\Anaconda\lib\site-packages\sqlalchemy\sql\schema.pyc in create(self, bind, checkfirst)
    646         bind._run_visitor(ddl.SchemaGenerator,
    647                             self,
--> 648                             checkfirst=checkfirst)
    649 
    650     def drop(self, bind=None, checkfirst=False):

C:\Anaconda\lib\site-packages\sqlalchemy\engine\base.pyc in _run_visitor(self, visitorcallable, element, connection, **kwargs)
   1545                                     connection=None, **kwargs):
   1546         with self._optional_conn_ctx_manager(connection) as conn:
-> 1547             conn._run_visitor(visitorcallable, element, **kwargs)
   1548 
   1549     class _trans_ctx(object):

C:\Anaconda\lib\site-packages\sqlalchemy\engine\base.pyc in _run_visitor(self, visitorcallable, element, **kwargs)
   1192     def _run_visitor(self, visitorcallable, element, **kwargs):
   1193         visitorcallable(self.dialect, self,
-> 1194                             **kwargs).traverse_single(element)
   1195 
   1196 

C:\Anaconda\lib\site-packages\sqlalchemy\sql\visitors.pyc in traverse_single(self, obj, **kw)
    117             meth = getattr(v, "visit_%s" % obj.__visit_name__, None)
    118             if meth:
--> 119                 return meth(obj, **kw)
    120 
    121     def iterate(self, obj):

C:\Anaconda\lib\site-packages\sqlalchemy\sql\ddl.pyc in visit_table(self, table, create_ok)
    726                 self.traverse_single(column.default)
    727 
--> 728         self.connection.execute(CreateTable(table))
    729 
    730         if hasattr(table, 'indexes'):

C:\Anaconda\lib\site-packages\sqlalchemy\engine\base.pyc in execute(self, object, *multiparams, **params)
    718                                 type(object))
    719         else:
--> 720             return meth(self, multiparams, params)
    721 
    722     def _execute_function(self, func, multiparams, params):

C:\Anaconda\lib\site-packages\sqlalchemy\sql\ddl.pyc in _execute_on_connection(self, connection, multiparams, params)
     65 
     66     def _execute_on_connection(self, connection, multiparams, params):
---> 67         return connection._execute_ddl(self, multiparams, params)
     68 
     69     def execute(self, bind=None, target=None):

C:\Anaconda\lib\site-packages\sqlalchemy\engine\base.pyc in _execute_ddl(self, ddl, multiparams, params)
    772             compiled,
    773             None,
--> 774             compiled
    775         )
    776         if self._has_events or self.engine._has_events:

C:\Anaconda\lib\site-packages\sqlalchemy\engine\base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
    945                                 parameters,
    946                                 cursor,
--> 947                                 context)
    948 
    949         if self._has_events or self.engine._has_events:

C:\Anaconda\lib\site-packages\sqlalchemy\engine\base.pyc in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
   1106                                         self.dialect.dbapi.Error,
   1107                                         connection_invalidated=self._is_disconnect),
-> 1108                                     exc_info
   1109                                 )
   1110 

C:\Anaconda\lib\site-packages\sqlalchemy\util\compat.pyc in raise_from_cause(exception, exc_info)
    183             exc_info = sys.exc_info()
    184         exc_type, exc_value, exc_tb = exc_info
--> 185         reraise(type(exception), exception, tb=exc_tb)
    186 
    187 if py3k:

C:\Anaconda\lib\site-packages\sqlalchemy\engine\base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
    938                                      statement,
    939                                      parameters,
--> 940                                      context)
    941         except Exception as e:
    942             self._handle_dbapi_exception(

C:\Anaconda\lib\site-packages\sqlalchemy\engine\default.pyc in do_execute(self, cursor, statement, parameters, context)
    433 
    434     def do_execute(self, cursor, statement, parameters, context=None):
--> 435         cursor.execute(statement, parameters)
    436 
    437     def do_execute_no_params(self, cursor, statement, context=None):

C:\Anaconda\lib\site-packages\MySQLdb\cursors.pyc in execute(self, query, args)
    203             del tb
    204             self.messages.append((exc, value))
--> 205             self.errorhandler(self, exc, value)
    206         self._executed = query
    207         if not self._defer_warnings: self._warning_check()

C:\Anaconda\lib\site-packages\MySQLdb\connections.pyc in defaulterrorhandler(***failed resolving arguments***)
     34     del cursor
     35     del connection
---> 36     raise errorclass, errorvalue
     37 
     38 re_numeric_part = re.compile(r"^(\d+)")

OperationalError: (OperationalError) (1050, "Table 'foo' already exists") '\nCREATE TABLE `Foo` (\n\t`index` INTEGER, \n\tanimal TEXT, \n\tlanguage TEXT\n)\n\n' ()

I haven't poked around the code to see if this is a SQLAlchemy issue or a pandas issue, but I'd hope it shouldn't be too difficult to fix

Metadata

Metadata

Assignees

No one assigned

    Labels

    IO SQLto_sql, read_sql, read_sql_query

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions