Hello I\'m trying to port a legacy application to python with sqlalchemy.
The application\'s existing database has about 300 tables and in every table there is a col
You can have your cake and eat it too. Define the columns you want to rename; sqlalchemy will automatically infer any columns you don't mention.
>>> from sqlalchemy import *
>>> from sqlalchemy.ext.declarative import declarative_base
>>>
>>> engine = create_engine("sqlite:///:memory:")
>>>
>>> engine.execute("""
... create table accnt (
... id integer primary key,
... code varchar(20),
... def varchar(50)
... )
... """)
>>>
>>> Base = declarative_base()
>>>
>>> Base.metadata.bind = engine
>>>
>>> class Accnt(Base):
... __tablename__ = 'accnt'
... __table_args__ = {'autoload': True}
... def_ = Column('def', String)
...
>>> Accnt.def_
>>> Accnt.code
>>>
EDIT:
By supplying a __table__
argument, you're telling the declarative extension that you already have a properly configured Table
that you'd like to use. But that's not true; you want to have the def
column referred to by another name in the class. By using __tablename__
and __table_args__
, you defer the construction of the table until after you've told declarative how you want to use that table. There's no elegant work-around if you are dead set on using __table__
. You can provide a property
that aliases the column or you may be able to specify the column as _def = getattr(__table__.c, 'def')
.
Really, you should just use __tablename__
; It's both more convenient and more flexible, and this is a great example of why.
(as an aside, it's most conventional to give alternate identifiers a trailing underscore instead of a leading underscore, use def_
instead of _def
; leading underscores usually signify that the name is 'private' or 'an implementation detail', if the name is meant to be public, but looks like a private name, it may cause more confusion than is necessary)