1
votes

I have object like below:

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)

and two models as below:

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

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

I am getting a warning

SAWarning: Column 'requesting_user_id' on table Table('friendship', MetaData(bind=None), Column('id', Integer(), table=, primary_key=True, nullable=False), Column('date', DateTime(), 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) being replaced by Column('requesting_user_id', Integer(), ForeignKey('user.id'), table=, nullable=False), which has the same key. Consider use_labels for select() statements.

Is there any way to make this warning go? or I should not be worried as its just giving me warning so that I should be careful while making SELECT statements?

1

1 Answers

7
votes

The root of the problem is the __table_args__ attribute that is shared between FriendshipLike and its subclasses. That too should be a declared_attr, or else the Table instances of subclasses using the mixin will try and share the same UniqueConstraint object, which seems to cause all kinds of weird behaviour. Simply turn that in to a 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)

and the warnings go away. There's an example of defining indexes in mixins here. Note that you do not need to explicitly name the Column objects returned by the declared_attr attributes, since a column is automatically named after the attribute it is assigned to.