gpt4 book ai didi

python - SQLAlchemy 声明式具体自动加载表继承

转载 作者:太空宇宙 更新时间:2023-11-03 15:29:13 25 4
gpt4 key购买 nike

我有一个现有的数据库,想使用 SQLAlchemy 访问它。因为,数据库结构由另一段代码(实际上是 Django ORM)管理,我不想重复自己,描述每个表结构,我正在使用 autoload 自省(introspection)。我被一个简单的具体表继承困住了。

Payment                FooPayment
+ id (PK) <----FK------+ payment_ptr_id (PK)
+ user_id + foo
+ amount
+ date

这是代码,表 SQL 描述作为文档字符串:

class Payment(Base):
"""
CREATE TABLE payments(
id serial NOT NULL,
user_id integer NOT NULL,
amount numeric(11,2) NOT NULL,
date timestamp with time zone NOT NULL,
CONSTRAINT payment_pkey PRIMARY KEY (id),
CONSTRAINT payment_user_id_fkey FOREIGN KEY (user_id)
REFERENCES users (id) MATCH SIMPLE)
"""
__tablename__ = 'payments'
__table_args__ = {'autoload': True}
# user = relation(User)

class FooPayment(Payment):
"""
CREATE TABLE payments_foo(
payment_ptr_id integer NOT NULL,
foo integer NOT NULL,
CONSTRAINT payments_foo_pkey PRIMARY KEY (payment_ptr_id),
CONSTRAINT payments_foo_payment_ptr_id_fkey
FOREIGN KEY (payment_ptr_id)
REFERENCES payments (id) MATCH SIMPLE)
"""
__tablename__ = 'payments_foo'
__table_args__ = {'autoload': True}
__mapper_args__ = {'concrete': True}

实际的表格有额外的列,但这与问题完全无关,所以为了尽量减少代码,我将所有内容都简化到了核心。

问题是,当我运行这个时:

payment = session.query(FooPayment).filter(Payment.amount >= 200.0).first()
print payment.date

生成的 SQL 是无意义的(注意缺少连接条件):

SELECT payments_foo.payment_ptr_id AS payments_foo_payment_ptr_id,
... /* More `payments_foo' columns and NO columns from `payments' */
FROM payments_foo, payments
WHERE payments.amount >= 200.0 LIMIT 1 OFFSET 0

当我尝试访问 payment.date 时,我收到以下错误:Concrete Mapper|FooPayment|payments_foo does not implement attribute u'date' at the instance level.

我尝试将隐式外键引用 id = Column('payment_ptr_id', Integer, ForeignKey('payments_payment.id'), primary_key=True) 添加到 FooPayment 没有任何成功。尝试 print session.query(Payment).first().user 工作(我省略了 User 类并注释了该行)完美,所以 FK 自省(introspection)工作。

如何对 FooPayment 执行简单查询并从结果实例访问 Payment 的值?

我正在使用 SQLAlchemy 0.5.3、PostgreSQL 8.3、psycopg2 和 Python 2.5.2。感谢您的任何建议。

最佳答案

你的表结构类似于联合表继承中使用的表结构,但它们肯定不对应于父类的所有字段在子类表中重复的具体表继承。现在你有一个子类,它的字段比父类少,并且有一个对父类实例的引用。切换到联合表继承(并在您的条件中使用 FooPayment.amount 或放弃继承以支持简单聚合(引用)。

按其他模型中的字段过滤不会自动添加连接条件。虽然很明显在您的示例中应该使用什么条件,但通常无法确定这种条件。这就是为什么您必须定义引用 Payment 的关系属性并在过滤器中使用其 has() 方法以获得正确的连接条件。

关于python - SQLAlchemy 声明式具体自动加载表继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1633447/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com