SQLAlchemy - AttributeError: 'Table' object has no attribute replace

iamgollum613 picture iamgollum613 · Aug 8, 2013 · Viewed 12.4k times · Source

I am trying to extract schema from a table in one database and transfer it to another database. The following is a portion of the function which performs this operation. It errors out when Table( ... ) is called.

Function Sample:

def transfer_data(self, from_db, to_db, tables, flush_interval=1000, table_data_filters = {}):
    if from_db is to_db or from_db == to_db:
        raise Exception("""Usage: Can't transfer tables to and from the same database!""")

    source, sengine = (from_db.new_session(), from_db.engine()) if isinstance(from_db, SessionManager) else self.__make_session(from_db)
    dest, dengine = (to_db.new_session(), to_db.engine()) if isinstance(to_db, SessionManager) else self.__make_session(to_db)
    meta = MetaData()
    with source.no_autoflush and dest.no_autoflush:
        for table_name in tables:
            print 'Processing', table_name
            print 'Pulling schema from source server'
            # ERROR OCCURS BELOW WITH CALL TO Table
            table = Table(table_name, meta, autoload=True, autoload_with=sengine)
            # etc...
            # etc...

Error Output:

table = Table(table_name, meta, autoload=True, autoload_with=sengine)
File "C:\Anaconda\lib\site-packages\sqlalchemy\schema.py", line 332, in __new__
table._init(name, metadata, *args, **kw)
File "C:\Anaconda\lib\site-packages\sqlalchemy\schema.py", line 396, in _init
self._autoload(metadata, autoload_with, include_columns)
File "C:\Anaconda\lib\site-packages\sqlalchemy\schema.py", line 413, in _autoload
self, include_columns, exclude_columns
File "C:\Anaconda\lib\site-packages\sqlalchemy\engine\base.py", line 1595, in run_callable
return conn.run_callable(callable_, *args, **kwargs)
File "C:\Anaconda\lib\site-packages\sqlalchemy\engine\base.py", line 1118, in run_callable
return callable_(self, *args, **kwargs)
File "C:\Anaconda\lib\site-packages\sqlalchemy\engine\default.py", line 262, in reflecttable
return insp.reflecttable(table, include_columns, exclude_columns)
File "C:\Anaconda\lib\site-packages\sqlalchemy\engine\reflection.py", line 397, in reflecttable
for col_d in self.get_columns(table_name, schema, **tblkw):
File "C:\Anaconda\lib\site-packages\sqlalchemy\engine\reflection.py", line 254, in get_columns
**kw)
File "<string>", line 1, in <lambda>
File "C:\Anaconda\lib\site-packages\sqlalchemy\engine\reflection.py", line 49, in cache
ret = fn(self, con, *args, **kw)
File "C:\Anaconda\lib\site-packages\sqlalchemy\dialects\sqlite\base.py", line 779, in get_columns
qtable = quote(table_name)
File "C:\Anaconda\lib\site-packages\sqlalchemy\sql\compiler.py", line 2350, in quote_identifier
self._escape_identifier(value) + \
File "C:\Anaconda\lib\site-packages\sqlalchemy\sql\compiler.py", line 2331, in _escape_identifier
return value.replace(self.escape_quote, self.escape_to_quote)
AttributeError: 'Table' object has no attribute 'replace'

Observation:

I think this has to do with unicode (ie. basestring) and how the sql compiler is dealing with it since unicode has a replace function. If value is of type Table than I imagine depending on the encoding of the database schema (which in my case is unicode), Table via some dynamic mix in class or through some other oop mechanism / design pattern becomes a type of unicode where replace is an inherited attribute/operation that is called implicitly or redefined somewhere.

Link to source code: https://bitbucket.org/shaung/sqlalchemy/src/b0a77b7e42f1/lib/sqlalchemy/sql/compiler.py

Documentation: http://docs.sqlalchemy.org/en/rel_0_8/core/schema.html#metadata-reflection

Any help would be greatly appreciated. - I am using Anaconda 1.6.2 for my development environment - I was using postgres for database backend but switched to sqlite since database was very small. - SQL Alchemy models are using the declarative syntax hence alchemy uses reflection - Windows 7, 64 bit (was on Ubuntu)

Answer

iamgollum613 picture iamgollum613 · Aug 9, 2013

This error occurs when Table() expects a table name of type string (hence access to replace function) and it instead as the error indicates was a Table object not to be confused with the actual Table() constructor that misguided the diagnosis.

A lesson in proper variable naming or knowing whats being passed in from the outside before hand and coding to convention accordingly.

Also for those who are interested you can also use: meta.reflect(bind=sengine) and then later on use ... table = meta.tables[ name_of_your_table ]

The stack trace which indicated the problem was this:

File "C:\Anaconda\lib\site-packages\sqlalchemy\dialects\sqlite\base.py", line 779, in get_columns qtable = quote(table_name)