Amin Etesamian
Amin Etesamian

Reputation: 3699

sqlalachmey add object to db based on specific criteria

As you know in a website like Stackoverflow, when your reputation reaches a specific value or when you answer a certain amount of questions related to a specific tag, you are awarded with a badge. How does one implement that? for example if I want to give a user a badge whenever his reputation reaches 500, should I check his reputation anytime the reputation changes to see if it is 500 or not? I really got no clue around this. Suppose these as my Account and Badge models.

association_table = Table(
    'account_badge', DeclarativeBase.metadata,
    Column('account_id', Integer, ForeignKey('accounts.id')),
    Column('badge_id', Integer, ForeignKey('badges.id'))
)


class Account(DeclarativeBase):

    __tablename__ = 'accounts'

    id = Column(Integer, primary_key=True)
    username = Column(Unicode(25), unique=True, nullable=False)
    _password = Column('password', Unicode(128))
    email_address = Column(Unicode(50), unique=True, nullable=False)
    bio = Column(Unicode(1000), nullable=True)
    reputation = Column(Integer, default=0)
    created = Column(DateTime, default=datetime.now)

    posts = relationship('Post', backref=backref('accounts'), cascade="all, delete-orphan")
    views = relationship('View', backref=backref('accounts'), cascade="all, delete-orphan")
    votes = relationship('Vote', backref=backref('votes'), cascade="all, delete-orphan")
    badges = relationship(
        "Badge",
        secondary=association_table,
        back_populates="accounts")
    password = synonym('_password', descriptor=property(_get_password,
                                                    _set_password))



class Badge(DeclarativeBase):
    __tablename__ = 'badges'

    id = Column(Integer, primary_key=True)
    _type = Column(Enum('Gold', 'Silver', 'Bronze', name='badge_type'))
    accounts = relationship(
        "Account",
        secondary=association_table,
        back_populates="badges")

Upvotes: 0

Views: 76

Answers (1)

metmirr
metmirr

Reputation: 4312

You can use after_update event:

from sqlalchemy import event

class Account(DeclarativeBase):
    ...

def check_for_reputation(mapper, connection, target):
    # 'target' is the updated object
    if target.reputation > 500:
        # do your work here

event.listen(Account, 'after_update', check_for_reputation)

Upvotes: 1

Related Questions