J'utilise SQLAlchemy pour remplir une base de données et souvent, je dois vérifier si un objet orm existe dans une base de données avant le traitement. C'est peut-être une question non conventionnelle, mais je me suis souvent retrouvé face à ce schéma:
my_object = session.query(SomeObject).filter(some_fiter).first()
if my_object: # Mostly in databases...
# Juchee it exists
# process
else:
# It does not exist. :-(
my_object = SomeObject()
# process
Ce que je suis en train de rêver de serait quelque chose comme:
if my_object = session.query(someObject).blabla.first():
# if my_object is None this scope is left alone
# if my_object is not None I can work with my_object here...
Je sais que cette syntaxe est fausse, mais je voulais expliquer ce que je veux dire par cet exemple. Tout moyen équivalent me rendrait heureux.
Existe-t-il une approche élégante en python pour ce modèle? Cette question vise non seulement SQLAlchemy, mais chaque scénario équivalent.
fermer les yeux en tapant "Postez votre question" et attendre que les gens intelligents et les pythonistes me traquent pour me traquer après avoir demandé quelque chose peut-être inapproprié ;-)
Vous voulez exécuter une requête Exist pour être efficace
(ret, ), = Session.query(exists().where(SomeObject.field==value))
Mike Bayer l'explique dans son blog:
http://techspot.zzzeek.org/2008/09/09/selecting-booleans/
Vous pouvez utiliser scalar si vous ne voulez pas avoir un tuple comme résultat:
ret = Session.query(exists().where(SomeObject.field==value)).scalar()
Cette question a été posée il y a longtemps, mais pour les futurs visiteurs un moyen plus concis de vérifier est
if session.query(model).filter(some_filter).count():
# do stuff
envelopper sur une fonction (volée sans vergogne à Django get_or_create, cela ne retourne pas un tuple)
get_or_create(model, **kwargs):
try:
# basically check the obj from the db, this syntax might be wrong
object = session.query(model).filter(**kwargs).first()
return object
except DoesNotExistException: # or whatever error/exception it is on SQLA
object = model()
# do it here if you want to save the obj to the db
return object
c'est tout. pour l'utiliser:
obj = get_or_create(SomeObject, filters)
changez le **kwargs
en un argument simple (comme some_filters) si vous voulez
essaie d’envelopper quelque chose que vous utilisez souvent (envelopper les fonctions ou les classes)
c’est seulement du pseudo-code, il peut y avoir une erreur de syntaxe.
EDIT: accentuer
Je sais que ce n'est pas tout, mais est-ce acceptable?
my_object = session.query(SomeObject).filter(some_filter).first()
if my_object is None:
my_object = SomeObject()
#process
from sqlalchemy.orm.util import has_identity
my_object = session.query(SomeObject).get(id) or SomeObject()
# Processing...
# Check if the object exists in the database
if not has_identity(my_object):
session.add(my_object)
session.commit()
.get () peut être remplacé par un filtre () + first () si nécessaire
if DBSession.query(ObjectType).filter(ObjectType.some_parametter == "This").first() is None:
C'est un moyen efficace de vérifier si un enregistrement existe sur une ligne. Il est efficace car il ne saisit que le premier objet. Il peut être placé sur une seule ligne car first () ne renvoie aucun lorsqu'il n'y a pas d'enregistrements correspondants. J'espère que cela pourra aider!
Vous pouvez utiliser ceci:
sth = session.query.filter_by().first()
if sth is None:
....
else:
....
Je l'ai testé. Cela fonctionne bien.
Quelques suggestions intéressantes ici. Pourquoi ne pas utiliser l'exception NoResultFound?
try:
existing = dbsession.query(SomeObject).filter_by(value=value).one()
return existing
except sqlalchemy.orm.exc.NoResultFound:
obj = SomeObject()