sqlalchemy-如何优雅地检查对象/实例/变量的存在,并同时将其分配给变量(如果存在于python中)?

我正在使用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

我梦of以求的是:

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,而且针对每个等效方案。

闭上眼睛打“发表您的问题”,并真诚地等待聪明的人和pythonistas追捕我,问可能不适当的问题;-)

Aufwind asked 2019-10-09T06:50:28Z
8个解决方案
89 votes

您想要执行一个现有查询以提高效率

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

Mike Bayer在他的博客文章中对此进行了解释:
[http://techspot.zzzeek.org/2008/09/09/selecting-booleans/]

如果不想使用元组,可以使用标量:

ret = Session.query(exists().where(SomeObject.field==value)).scalar()
Rach answered 2019-10-09T06:50:59Z
21 votes

这是很久以前问过的,但对以后的访客来说,一种更简洁的检查方法是

 if session.query(model).filter(some_filter).count():
     # do stuff
elbear answered 2019-10-09T06:51:23Z
14 votes

将其包装在一个函数上(从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)

尝试包装您经常使用的东西(将它们包装到函数或类中)

多数民众赞成只有伪代码,可能有语法错误。

编辑:强调

kusut answered 2019-10-09T06:52:23Z
5 votes

我知道这不是全部步骤,但是可以接受吗?

my_object = session.query(SomeObject).filter(some_filter).first()
if my_object is None:
    my_object = SomeObject()
#process
multipleinterfaces answered 2019-10-09T06:52:48Z
4 votes
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()

Metalstorm answered 2019-10-09T06:53:13Z
2 votes
if DBSession.query(ObjectType).filter(ObjectType.some_parametter == "This").first() is None:

这是检查记录是否存在的一种有效的单行方式。 这是有效的,因为它仅捕获第一个对象,并且可以在一行上,因为在没有匹配记录时,first()返回None。 希望有帮助!

jmercouris answered 2019-10-09T06:53:38Z
0 votes

这里有一些不错的建议。 如何使用NoResultFound异常?

try:
    existing = dbsession.query(SomeObject).filter_by(value=value).one()
    return existing
except sqlalchemy.orm.exc.NoResultFound:
    obj = SomeObject()
suripoori answered 2019-10-09T06:54:02Z
0 votes

你可以用这个:

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

我已经测试过了,效果很好。

bass chuck answered 2019-10-09T06:54:28Z
translate from https://stackoverflow.com:/questions/6587879/how-to-elegantly-check-the-existence-of-an-object-instance-variable-and-simultan