web-dev-qa-db-fra.com

SQLAlchemy: une meilleure façon de mettre à jour avec déclarative?

Je suis un noob SQLAlchemy.

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

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

Lorsque je connais l'ID de l'utilisateur sans objet chargé dans la session, je mets à jour cet utilisateur comme ceci:

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

Je n'aime pas utiliser User.__table__, devrais-je arrêter de m'inquiéter avec ça?

Y a-t-il une meilleure manière de faire cela?

Merci!

43
Hadrien

Il existe également une capacité de mise à jour au niveau ORM. Il ne gère pas encore les cas délicats mais pour le cas trivial de la mise à jour sur une seule ligne (ou mise à jour en masse), cela fonctionne bien. Il passe même sur tous les objets déjà chargés et leur applique également la mise à jour. Vous pouvez l'utiliser comme ceci:

session.query(User).filter_by(id=123).update({"name": u"Bob Marley"})
60
Ants Aasma

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

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

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

mais il sera considérablement plus lent car il conduit à la construction de l'objet mappé. Et je ne suis pas sûr que ce soit plus lisible.

Dans l'exemple que vous avez fourni, je vois la solution la plus naturelle et la "bonne". Je ne m'inquiéterais pas pour les petits __table__ la magie.

17
nkrkv

Des fonctionnalités similaires sont disponibles via la méthode update() sur l'objet Table.

class User(Base):
    __table  = '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')

Utiliser User.__table__ est comment cela se fait dans SQLAlchemy.

2
The Demz