80 votes

Comment vérifier élégamment l'existence d'un objet/instance/variable et lui attribuer simultanément une variable si elle existe en python ?

Je utilise SQLAlchemy pour peupler une base de données et souvent j'ai besoin de vérifier si un objet orm existe dans une base de données avant de le traiter. Cela peut être une question non conventionnelle, mais je me suis souvent retrouvé confronté à ce schéma :

my_object = session.query(SomeObject).filter(some_fiter).first()
if my_object: # Mostly in databases...
    # Hourra il existe
    # traiter
else:
    # Il n'existe pas. :-(
    my_object = SomeObject()
    # traiter

Ce que je rêve serait quelque chose comme :

if my_object = session.query(someObject).blabla.first():
    # si my_object est None, ce domaine reste inchangé
    # si my_object n'est pas None, je peux travailler avec my_object ici...

Je sais que cette syntaxe est incorrecte, mais je voulais expliquer ce que je veux dire par cet exemple. Toute façon équivalente me rendrait heureux.

Existe-t-il une approche python élégante pour ce schéma ? Cette question vise non seulement SQLAlchemy, mais chaque scénario équivalent.

fermer les yeux en appuyant sur "Publier votre question" et en attendant que les gens intelligents et les pythonistas de coeur me pourchassent pour avoir posé quelque chose peut-être inapproprié ;-)

120voto

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 article de 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()

26voto

Cela a été demandé il y a longtemps, mais pour les visiteurs futurs, une façon plus concise de vérifier est

 si session.query(model).filter(some_filter).count():
     # faire quelque chose

14voto

kusut Points 890

Emballez-le dans une fonction (honteusement volé à django get_or_create, cela ne retourne cependant pas un tuple)

get_or_create(model, **kwargs):
    try:
        # vérifie essentiellement l'objet de la base de données, cette syntaxe pourrait être incorrecte
        object = session.query(model).filter(**kwargs).first()
        return object
    except DoesNotExistException: # ou toute autre erreur/exception sur SQLA
        object = model()
        # faites-le ici si vous voulez enregistrer l'objet dans la base de données
        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 le souhaitez

essayez d'encapsuler quelque chose que vous utilisez souvent (encapsulez-les dans des fonctions ou des classes)

ce n'est que du pseudo-code, il peut y avoir des erreurs de syntaxe.

EDIT : mettre en évidence

5voto

multipleinterfaces Points 2917

Je sais que ce n'est pas tout en une seule étape, mais est-ce acceptable?

my_object = session.query(SomeObject).filter(some_filter).first()
if my_object is None:
    my_object = SomeObject()
#process

4voto

Metalstorm Points 506
from sqlalchemy.orm.util import has_identity

mon_objet = session.query(SomeObject).get(id) or SomeObject()
# Traitement...

# Vérifier si l'objet existe dans la base de données
if not has_identity(mon_objet):
    session.add(mon_objet)

session.commit()

.get() peut être remplacé par un filtre() + first() si nécessaire

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X