当 2 个模型在 flask-sqlalchemy 中继承相同的对象时收到警告

Posted

技术标签:

【中文标题】当 2 个模型在 flask-sqlalchemy 中继承相同的对象时收到警告【英文标题】:Getting warning when 2 models inherit the same object in flask-sqlalchemy 【发布时间】:2017-10-13 22:37:31 【问题描述】:

我有如下对象:

class FriendshipLike(object):
__table_args__ = (
    db.UniqueConstraint('requesting_user_id', 'accepting_user_id', 'status',
                        name='unique_friendship'),
)
id = db.Column(db.Integer, primary_key=True, nullable=False)
date = db.Column(db.DateTime(), nullable=False,
                 default=datetime.datetime.now())

@declared_attr
def requesting_user_id(cls):
    return db.Column('requesting_user_id', db.Integer, db.ForeignKey(
        'user.id'), nullable=False)

@declared_attr
def accepting_user_id(cls):
    return db.Column('accepting_user_id', db.Integer, db.ForeignKey('user.id'),
                     nullable=False)

还有以下两种型号:

class Friendship(FriendshipLike, db.Model, CRUDMixin):
__tablename__ = 'friendship'

class Flirt(FriendshipLike, db.Model, CRUDMixin):
__tablename__ = 'flirt'

我收到警告

SAWarning:表 Table('friendship',MetaData(bind=None),Column('id',Integer(),table=,primary_key=True,nullable=False) 上的列 'requesting_user_id',Column('date ', DateTime(), table=, nullable=False, default=ColumnDefault(datetime.datetime(2017, 5, 15, 10, 0, 47, 646868))), Column('status', Enum('accepted', '待定','以下','拒绝'),table=,nullable=False,default=ColumnDefault('pending')),Column('requesting_user_id',Integer(),ForeignKey('user.id'),表=, nullable=False), Column('accepting_user_id', Integer(), ForeignKey('user.id'), table=, nullable=False), schema=None) 被 Column('requesting_user_id', Integer() 替换, ForeignKey('user.id'), table=, nullable=False), 有相同的key。考虑 select() 语句的 use_labels。

有什么办法可以消除这个警告吗?或者我不应该担心,因为它只是给我警告,所以我在做SELECT 声明时应该小心?

【问题讨论】:

【参考方案1】:

问题的根源在于__table_args__ 属性在FriendshipLike 及其子类之间共享。那也应该是declared_attr,否则使用mixin 的子类的Table 实例将尝试共享相同的UniqueConstraint 对象,这似乎会导致各种奇怪的行为。只需将其转为declared_attr

class FriendshipLike(object):

    @declared_attr
    def __table_args__(cls):
        return (
            db.UniqueConstraint('requesting_user_id',
                                'accepting_user_id',
                                'status',
                                name='unique_friendship'),
        )

    id = db.Column(db.Integer, primary_key=True, nullable=False)
    date = db.Column(db.DateTime(), nullable=False,
                     default=datetime.datetime.now())

    @declared_attr
    def requesting_user_id(cls):
        return db.Column('requesting_user_id', db.Integer, db.ForeignKey(
            'user.id'), nullable=False)

    @declared_attr
    def accepting_user_id(cls):
        return db.Column('accepting_user_id', db.Integer, db.ForeignKey('user.id'),
                         nullable=False)

警告消失了。有一个在 mixins here 中定义索引的例子。请注意,您不需要显式命名declared_attr 属性返回的Column 对象,因为a column is automatically named after the attribute it is assigned to。

【讨论】:

非常感谢您抽出宝贵时间进行解释:) 很好的答案。 如果我能投票 100 次,这让我很沮丧。

以上是关于当 2 个模型在 flask-sqlalchemy 中继承相同的对象时收到警告的主要内容,如果未能解决你的问题,请参考以下文章

Flask-SqlAlchemy - 与列''关联的外键无法找到表

ON_DELETE="CASCADE" 不适用于 flask-sqlalchemy

Flask-SQLAlchemy:用户角色模型和关系

Flask 学习-13.Flask-SQLAlchemy 新建模型和字段

在 flask-sqlalchemy 中使用具有相同模型的多个数据库

从 flask-sqlalchemy db 获取所有模型