it-swarm.com.de

Wie kann man elegant die Existenz eines Objekts/einer Instanz/einer Variablen prüfen und gleichzeitig einer Variablen zuweisen, wenn sie in Python existiert?

Ich benutze SQLAlchemy zum Auffüllen einer Datenbank und muss vor der Verarbeitung häufig prüfen, ob ein Orm-Objekt in einer Datenbank vorhanden ist. Dies mag eine unkonventionelle Frage sein, aber ich bin häufig auf dieses Muster gestoßen:

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

Wovon ich träume bin, wäre so etwas wie:

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...

Ich weiß, dass diese Syntax falsch ist, aber ich wollte erklären, was ich mit diesem Beispiel meine. Jeder äquivalente Weg würde mich glücklich machen.

Gibt es einen eleganten Python-Ansatz für dieses Muster? Diese Frage zielt nicht nur auf SQLAlchemy ab, sondern auf jedes äquivalente Szenario.

Ich schließe die Augen und tippe auf "Frage posten" und warte auswendig auf die klugen Leute und Pythonisten, die mich jagen, weil ich etwas Unangebrachtes gefragt habe ;-)

55
Aufwind

Sie möchten eine vorhandene Abfrage ausführen, um effizient zu sein

(ret, ), = Session.query(exists().where(SomeObject.field==value))

Mike Bayer erklärt es in seinem Blogpost:
http://techspot.zzzeek.org/2008/09/09/selecting-booleans/

Sie können scalar verwenden, wenn Sie kein Tuple als Ergebnis haben möchten:

ret = Session.query(exists().where(SomeObject.field==value)).scalar()
84
Rach

Dies wurde schon vor langer Zeit nachgefragt, aber für zukünftige Besucher ist es einfacher, dies zu überprüfen

 if session.query(model).filter(some_filter).count():
     # do stuff
22
elbear

wickle es auf eine Funktion (schamlos von Django get_or_create gestohlen, dies liefert jedoch kein 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

das ist es. um es zu benutzen:

obj = get_or_create(SomeObject, filters)

Ändern Sie den **kwargs in ein einfaches Argument (wie some_filters), wenn Sie möchten 

versuche etwas zu verpacken, das du oft benutzt (wickle sie in Funktionen oder Klassen ein)

das ist nur Pseudo-Code, es kann zu einem Syntaxfehler kommen.

BEARBEITEN: betonen

14
kusut

Ich weiß, es ist nicht alles ein Schritt, aber ist das akzeptabel?

my_object = session.query(SomeObject).filter(some_filter).first()
if my_object is None:
    my_object = SomeObject()
#process
5
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 () kann bei Bedarf durch ein filter () + first () ersetzt werden

4
Metalstorm
if DBSession.query(ObjectType).filter(ObjectType.some_parametter == "This").first() is None:

Dies ist eine effiziente Methode, um zu überprüfen, ob ein Datensatz vorhanden ist. Es ist effizient, da nur das erste Objekt erfasst wird, und es kann sich in einer Zeile befinden, da first () None zurückgibt, wenn keine passenden Datensätze vorhanden sind. Hoffentlich hilft das! 

1
jmercouris

Sie können dies verwenden:

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

Ich habe es getestet. Es funktioniert gut.

0
bass chuck

Einige nette Vorschläge hier. Wie wäre es mit der NoResultFound-Ausnahme?

try:
    existing = dbsession.query(SomeObject).filter_by(value=value).one()
    return existing
except sqlalchemy.orm.exc.NoResultFound:
    obj = SomeObject()
0
suripoori