Как элегантно проверить существование объекта / экземпляра / переменной и одновременно назначить его переменной, если он существует в python? - PullRequest
62 голосов
/ 05 июля 2011

Я использую SQLAlchemy для заполнения базы данных, и часто мне нужно проверить, существует ли объект orm в базе данных перед обработкой.Это может быть нетрадиционный вопрос, но я часто сталкиваюсь с такой схемой:

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

То, о чем я мечтаю , будет выглядеть примерно так:

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

Я знаю, что этот синтаксис неправильный, но я хотел объяснить, что я имею в виду под этим примером.Любой эквивалентный способ сделал бы меня счастливым.

Есть ли элегантный подход на python для этого шаблона?Этот вопрос направлен не только на SQLAlchemy, но и на каждый эквивалентный сценарий.

закрывая глаза, нажимая кнопку «Опубликовать свой вопрос» и ожидая, когда умные люди и питонисты наизусть выследят меня за то, что я спрашиваю, возможно, возможнонеуместно ; -)

Ответы [ 8 ]

92 голосов
/ 14 апреля 2013

Вы хотите выполнить запрос Exist, чтобы быть эффективным

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

Майк Байер объясняет это в своем блоге:
http://techspot.zzzeek.org/2008/09/09/selecting-booleans/

Вы можете использовать скаляр, если не хотите иметь кортеж в результате:

ret = Session.query(exists().where(SomeObject.field==value)).scalar()
21 голосов
/ 24 октября 2012

Это было задано давно, но для будущих посетителей более краткий способ проверить это

 if session.query(model).filter(some_filter).count():
     # do stuff
14 голосов
/ 06 июля 2011

обернуть его в функцию (бессовестно украденную из django get_or_create, хотя это не возвращает кортеж)

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

вот и все.чтобы использовать его:

obj = get_or_create(SomeObject, filters)

замените **kwargs на простой аргумент (например, some_filters), если вы хотите

попытаться обернуть то, что вы часто используете (обернуть их в функцииили классы)

это только псевдокод, может быть синтаксическая ошибка.

РЕДАКТИРОВАТЬ: выделите

5 голосов
/ 06 июля 2011

Я знаю, что это не один шаг, но это приемлемо?

my_object = session.query(SomeObject).filter(some_filter).first()
if my_object is None:
    my_object = SomeObject()
#process
4 голосов
/ 30 октября 2014
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 () можно заменить на filter () + first () при необходимости

2 голосов
/ 06 декабря 2015
if DBSession.query(ObjectType).filter(ObjectType.some_parametter == "This").first() is None:

Это эффективный однострочный способ проверки существования записи.Он эффективен, потому что он захватывает только первый объект, и он может находиться в одной строке, потому что first () возвращает None, когда нет соответствующих записей.Надеюсь, это поможет!

0 голосов
/ 30 августа 2017

Вы можете использовать это:

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

Я это проверил. Хорошо работает.

0 голосов
/ 30 ноября 2016

Несколько приятных предложений здесь. Как насчет использования исключения NoResultFound?

try:
    existing = dbsession.query(SomeObject).filter_by(value=value).one()
    return existing
except sqlalchemy.orm.exc.NoResultFound:
    obj = SomeObject()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...