cte*_*giz 10 python sqlalchemy
您好我正在尝试使用sqlalchemy将遗留应用程序移植到python.
应用程序的现有数据库有大约300个表,每个表中都有一个名为def的列,如:
create table accnt (
code varchar(20)
, def varchar(50) --for accnt definition
, ...
)
Run Code Online (Sandbox Code Playgroud)
因此,当使用声明性语法和反射时,我可以轻松地创建我的类:
class Accnt(Base):
__table__ = Table('accnt', metadata, autoload = True, autoload_with=engine)
Run Code Online (Sandbox Code Playgroud)
但是当我试图达到def列时,我最终得到一个错误.例如 :
q = session.query(Accnt)
for row in q:
print q.def
Run Code Online (Sandbox Code Playgroud)
因为def是python的保留字:(
要克服这个问题,我可以创建我的课程:
class Accnt(Base):
__table__ = Table('accnt', metadata, autoload = True, autoload_with=engine)
__mapper_args__ = {'column_prefix':'_'}
Run Code Online (Sandbox Code Playgroud)
但是在每个列名前放一个_是无聊的,而不是花哨的.
我想要做的是访问def列与另一个名称/(键?).
有任何想法吗?
---编辑---(根据TokenMacGuy的要求编辑原帖)
虽然我已经接受了TokenMacGuy的回答,但我之前尝试过:
engine = create_engine('firebird://sysdba:masterkey@127.0.0.1/d:\\prj\\db2\\makki.fdb?charse??t=WIN1254', echo=False)
metadata = MetaData()
DbSession = sessionmaker(bind=engine)
Base = declarative_base()
class Accnt(Base):
__table__ = Table('accnt', metadata, autoload = True, autoload_with=engine)
_def = Column("def", String(50))
Run Code Online (Sandbox Code Playgroud)
我有sqlalchemy.exc.ArgumentError:指定表错误时无法添加额外的列'def'.
我和TokenMacGuy之间的主要区别是
mine : _table_ ....
TokenMcGuy : __tablename__ = 'accnt'
__table_args__ = {'autoload': True}
Run Code Online (Sandbox Code Playgroud)
和元数据绑定......
那么,为什么我以前的尝试产生错误?
Sin*_*ion 15
你可以吃蛋糕,也可以吃.定义要重命名的列; sqlalchemy将自动推断您未提及的任何列.
>>> 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)
... )
... """)
<sqlalchemy.engine.base.ResultProxy object at 0x2122750>
>>>
>>> Base = declarative_base()
>>>
>>> Base.metadata.bind = engine
>>>
>>> class Accnt(Base):
... __tablename__ = 'accnt'
... __table_args__ = {'autoload': True}
... def_ = Column('def', String)
...
>>> Accnt.def_
<sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x2122e90>
>>> Accnt.code
<sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x2127090>
>>>
Run Code Online (Sandbox Code Playgroud)
编辑:
通过提供__table__参数,您告诉声明性扩展,您已经有一个Table您想要使用的正确配置.但事实并非如此; 您希望def在类中使用另一个名称引用该列.通过使用__tablename__和__table_args__,你推迟表的构造,直到你告诉声明如何使用该表.如果您已经无法使用,那么就没有优雅的解决方法__table__.您可以为property列提供别名,或者您可以将列指定为_def = getattr(__table__.c, 'def').
真的,你应该使用__tablename__; 它既方便又灵活,这就是原因的一个很好的例子.
(顺便说一句,最常见的是给备用标识符一个尾随下划线而不是前导下划线,def_而不是使用_def;前导下划线通常表示名称是'私有'或'实现细节',如果名称是公共,但看起来像一个私人名称,它可能会导致比必要更多的混乱)
| 归档时间: |
|
| 查看次数: |
9944 次 |
| 最近记录: |