web-dev-qa-db-fra.com

Comment vérifier avec élégance l'existence d'un objet/instance/variable et l'affecter simultanément à une variable s'il existe en python

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é ;-)

55
Aufwind

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()
84
Rach

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
22
elbear

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

14
kusut

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
5
multipleinterfaces
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

4
Metalstorm
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! 

1
jmercouris

Vous pouvez utiliser ceci:

sth = session.query.filter_by().first()
if sth is None:
    ....
else:
    ....

Je l'ai testé. Cela fonctionne bien.

0
bass chuck

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()
0
suripoori