【问题标题】:Flask-SQLAlchemy using STI: how to automatically substitute type fieldFlask-SQLAlchemy 使用 STI:如何自动替换类型字段
【发布时间】:2017-03-02 18:44:18
【问题描述】:

我正在使用 Flask-SQLAlchemy==2.2 并且有这样的 STI (Single Table Inheritance) 配置:

from flask_sqlalchemy import SQLAlchemy


db = SQLAlchemy()


class Item(db.Model):
    __tablename__ = 'item'

    id = db.Column(db.Integer, primary_key=True)
    info = db.Column(db.String(255))
    type = db.Column(db.String())

    __mapper_args__ = {
        'polymorphic_on': type
    }


class ItemA(Item):
    __mapper_args__ = {
        'polymorphic_identity': 'a'
    }


class ItemB(Item):
    __mapper_args__ = {
        'polymorphic_identity': 'b'
    }


class ItemC(Item):
    __mapper_args__ = {
        'polymorphic_identity': 'c'
    }

我想查询特定种类的项目。我可以这样做:

Item.query.filter_by(type='b').all()

有没有机会像下面这样做?

ItemB.query.all()

谢谢。

【问题讨论】:

  • 是的,应该可以的。
  • @univerio:不幸的是,它只返回所有对象(不是 type=='b')
  • 逐字使用您的配置,呈现的 SQL 为 SELECT item.id AS item_id, item.info AS item_info, item.type AS item_type FROM item WHERE item.type IN (?)
  • 我对@9​​87654327@有不同的输出
  • 除了it works for me,我不知道该说什么。

标签: sql python-3.x sqlalchemy flask-sqlalchemy sti


【解决方案1】:

它不起作用,因为您不小心使用了连接表继承。 flask-sqlalchemy 自动为您设置__tablename__。如果您想要单表继承,则需要将其显式设置为None

class ItemB(Item):
    __tablename__ = None
    __mapper_args__ = {
        'polymorphic_identity': 'b'
    }

【讨论】:

  • 非常感谢@univerio! :) 您使我免于使用 hacky 解决方案并花费更多时间了解为什么会这样。顺便说一句,我刚刚在 Github (github.com/mitsuhiko/flask-sqlalchemy/issues/481) 上发布了这个问题。
  • 顺便说一句,你知道为什么会发生这种行为吗?有没有办法默认禁用它?
  • 我也刚刚注意到它只发生在 Flask-SQLAlchemy==2.2(2.1 可以)。
  • @dizpers Auto-setting __tablename__ 至少从 0.12(6 年前)开始就在 flask-sqlalchemy 中,如果不是更早的话。
  • 明白了。我刚刚检查了 2.1 和 2.2 - __tablename__ 设置为 item。同时在 2.1 中我得到了正确的查询,在 2.2 中我得到了错误的查询。
猜你喜欢
  • 2012-08-22
  • 1970-01-01
  • 2010-12-01
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 2019-03-14
  • 2015-10-26
  • 2021-04-12
相关资源
最近更新 更多