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

Pra*_*epb 1 python sqlalchemy flask flask-sqlalchemy

我有如下对象:

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)
Run Code Online (Sandbox Code Playgroud)

和两个模型如下:

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

class Flirt(FriendshipLike, db.Model, CRUDMixin):
__tablename__ = 'flirt'
Run Code Online (Sandbox Code Playgroud)

我收到警告

SAWarning: 表 Table('friendship', MetaData(bind=None), Column('id', Integer(), table=, primary_key=True, nullable=False), Column('date', DateTime) 上的列 'requesting_user_id' (), table=, nullable=False, default=ColumnDefault(datetime.datetime(2017, 5, 15, 10, 0, 47, 646868))), Column('status', Enum('accepted', 'pending') , 'following', 'denied'), table=, nullable=False, default=ColumnDefault('pending')), Column('requesting_user_id', Integer(), ForeignKey('user.id'), table=, 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),具有相同的键。考虑 use_labels 用于 select() 语句。

有没有办法让这个警告消失?或者我不应该担心,因为它只是给我警告,所以我在SELECT发表声明时应该小心?

Ilj*_*ilä 7

问题的根源__table_args__FriendshipLike于其子类之间共享的属性。那也应该是 a declared_attr,否则Table使用 mixin 的子类的实例将尝试共享相同的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)
Run Code Online (Sandbox Code Playgroud)

并且警告消失了。有一个在混入定义索引的例子在这里。请注意,您不需要显式命名Columndeclared_attr属性返回的对象,因为列会自动以其分配给的属性命名