Problem: Recalculate email hash when it changes. I go to the forehead:

class User(db.Model): __tablename__ = "users" id = db.Column(db.Integer, primary_key=True) nickname = db.Column(db.String(64), index=True, unique=True, nullable=False) email = db.Column(db.String(120), index=True, unique=True, nullable=False) email_hash = db.Column(db.String(32)) @property def email(self): return self.email @email.setter def email(self, email): #считаем хэш self.email_hash=hash self.email = email 

The solution is to change the name of the attribute to _email so that it does not conflict with the name of the property, but this method is not acceptable, since the class is a display of real tables in which underscores and other shamanism with names are not allowed.

    2 answers 2

    The correspondence between the attribute name and the field name in the table is easy to change:

     _email = db.Column('email', db.String(120), index=True, unique=True, nullable=False) 

      The model is not a display of real tables, the model is the essence of the subject area. Such differences allow settling more logic in the model.

      True, this option is not obvious - I have never met him "in battle" and there is nothing in the documentation about such tricks.

      To implement such manipulations, the save method is often used. Of course, the hash will not appear on the fly, but only after saving to the database, but usually this is enough. Example:

       class User(db.Model): def save(self, *args, **kwargs): self.hash = md5(self.email) super(User, self).save(*args, **kwargs) 

      Another example in the documentation .

      • Interesting, but as I understand it, the parent method save () is redefined here, in SQLAlchemy everything is a little different. In addition, because then it remains possible to shoot yourself in the foot by: vasya.email = 'anothermail@example.com #save() не будет вызван - хэш не пересчитается - aryndin
      • one
        In Alchemy, there are MapperEvents for this. Found the right knock on the Alchemy documentation , there is an answer to the question. @ sergey-gornostaev suggested the correct version. - Lebedev Ilya
      • Thanks for the reference, what you need. It seems that @ sergey-gornostaev + suggested some special DB-oriented methods. - aryndin