2010-04-13 3 views
36

Je suis un SQLAlchemy noob.SQLAlchemy: un meilleur moyen de mise à jour avec déclaratif?

Disons que j'ai une table utilisateur en mode déclaratif:

ex = update(User.__table__).where(User.id==123).values(name=u"Bob Marley") 
Session.execute(ex) 

Je n'aime pas en utilisant:

class User(Base): 
    __tablename__ = 'user' 
    id = Column(u'id', Integer(), primary_key=True) 
    name = Column(u'name', String(50)) 

Quand je sais, je mettre à jour cet utilisateur comme l'identifiant de l'utilisateur sans objet chargé dans la session User.__table__, devrais-je arrêter de m'inquiéter avec ça?

Y a-t-il une meilleure façon de procéder?

Merci!

+1

mise à jour http://docs.sqlalchemy.org/fr/rel_1_0/core/dml.html#sqlalchemy.sql.expression.update –

Répondre

55

Il y a aussi une certaine capacité de mise à jour au niveau ORM. Il ne gère pas les cas difficiles, mais pour le cas trivial de mise à jour d'une seule ligne (ou mise à jour en vrac), cela fonctionne très bien. Il va même au-dessus de tous les objets déjà chargés et applique la mise à jour sur eux aussi. Vous pouvez l'utiliser comme ceci:

session.query(User).filter_by(id=123).update({"name": u"Bob Marley"}) 
+2

Ceci ne prend pas en compte les noms de variable attribués par l'utilisateur pour les colonnes - If name ont été déclarés user_name = Column ("name", String (50)), cela échouerait b/c le nom réel de la colonne est requis. Quelqu'un peut-il expliquer pourquoi c'est? Si – Kira

+1

pas être soit '.get (123)' 'ou .filter_by (id == 123)'? – Brendan

+3

@Brendan '' filter' et filter_by' sont différentes méthodes. Le premier prend une expression comme argument tandis que le dernier prend des arguments de mot-clé. –

15

Vous travaillez sur clause niveau ici, pas sur le modèle/entité/niveau de l'objet. Le niveau de la clause est inférieur à celui des objets mappés. Et oui, il faut faire quelque chose pour convertir un terme en d'autres.

Vous pouvez également rester au niveau de l'objet et de le faire:

session = Session() 
u = session.query(User).get(123) 
u.name = u"Bob Marley" 
session.commit() 

mais il sera nettement plus lente car elle conduit à la construction d'objet mis en correspondance. Et je ne suis pas sûr que ce soit plus lisible.

Dans l'exemple de votre condition que je vois la solution la plus naturelle et « droit ». Je ne m'inquiéterais pas de la petite magie __table__.

2

fonctionnalités similaires est disponible via la méthode update() sur l'objet Table.

class User(Base): 
    __tablename__ = 'user' 
    id = Column('id', Integer(), primary_key=True) 
    name = Column('name', String(50)) 

stmt = User.__table__.update().where(User.id==5).values(name='user #5') 

Pour utiliser User.__table__ comment son fait dans SQLAlchemy.

Questions connexes