2017-08-12 3 views
1

Je construis une application web. j'ai le modèle suivant.Comment définir la valeur d'une colonne dans sqlalchemy en fonction de deux autres colonnes du même modèle?

class Staff(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    store_id = db.Column(db.Integer, db.ForeignKey('store.id')) 
    first_name = db.Column(db.String(64)) 
    last_name = db.Column(db.String(64)) 
    username = db.Column(db.String(64)) 
    cell_phone = db.Column(db.Integer) 
    email = db.Column(db.String(64)) 
    position = db.Column(db.String(64)) 
    # add average salary value based on payroll 

Je veux que le username d'être first_name+last_name avec l'utilisateur en tapant uniquement son prénom et le nom sous la forme.

Je sais comment utiliser @db.event.listens_for(Staff, "after_insert") etc et le mettre à jour comme ça. Mais y a-t-il un moyen de définir quelque chose dans le modèle de sorte qu'il le fasse automatiquement sans triger? `

Répondre

2

Vous devriez vous familiariser avec les décorateurs property.

Pour SQLAlchemy, il existe une extension hybrid_property que je recommande vivement d'apprendre et d'utiliser. Jetez un oeil à l'exemple:

from sqlalchemy.ext.hybrid import hybrid_property 

class Staff(db.Model): 
    first_name = db.Column(db.String(64)) 
    last_name = db.Column(db.String(64)) 

    @hybrid_property 
    def username(self): 
     return self.first_name + self.last_name 

montre exactement un Documentations tel usage des propriétés hybrides: SQL Expressions as Mapped Attributes: Using a Hybrid. En utilisant une propriété hybride, vous pouvez facilement utiliser nom d'utilisateur pour interroger vos modèles et vous n'avez pas besoin de stocker les données deux fois dans votre base de données. Avec quelques lignes supplémentaires, vous devriez être en mesure de create update constructs dans la prochaine SQLAlchemy v1.2.

Edit: Pour le dire explicitement - vous pouvez utiliser column_property aussi (comme indiqué dans liée documentation):

username = column_property(first_name + last_name) 

Ce qui peut sembler mieux, mais est moins puissant (n'a pas de déclaration de mise à jour entre autres).

PS. Je parie que c'est un doublon mais je ne peux pas trouver une question identique.

+0

si le nom d'utilisateur a 'db.Column (db.String (64))' dans votre réponse? puis-je aussi l'écrire comme une colonne? –

+0

Le nom d'utilisateur n'est pas une colonne. Il ne sera pas stocké dans la base de données (ce qui est une bonne chose) mais se comportera * comme une colonne. Par exemple, ayant préalablement créé 'Staff (first_name = 'John', last_name = 'Smith')' vous pouvez l'interroger avec 'Staff.query.filter_by (nom d'utilisateur = 'John Smith'). One()'. – krassowski

+0

Et la différence maximale de 'username' est 128; vous pouvez utiliser des validateurs pour restreindre la longueur sumarique de deux colonnes. Reportez-vous à cette discussion: https://stackoverflow.com/a/18580815/6646912 – krassowski