How to override a column name in sqlalchemy using reflection and descriptive syntax

前端 未结 3 1356
暖寄归人
暖寄归人 2020-12-30 08:40

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

3条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-30 09:08

    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)

提交回复
热议问题