如何优雅地检查一个对象/实例/变量的存在,并同时赋值给变量,如果它存在于 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

我的 做梦是这样的:

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,而且针对每个等价的场景。

闭上眼睛,点击“发布你的问题”,等待那些聪明人和蟒蛇爱好者用心追捕我,因为我问了一些可能不合适的问题

71282 次浏览

我知道这不是一步到位,但这可以接受吗?

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

将它包装在一个函数上(无耻地从 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 _ filter)

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

那只是伪代码,可能有语法错误。

编辑: 强调

很久以前就有人问过这个问题,但是对于未来的访问者来说,一个更简洁的检查方法是

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

您希望高效地执行 Exist 查询

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

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

这是检查记录是否存在的一种有效的单行方法。它之所以高效,是因为它只抓取第一个对象,而且它可以放在一行上,因为如果没有匹配的记录,first ()将返回 Nothing。希望能帮上忙!

这里有一些不错的建议。使用 NoResultfound 异常怎么样?

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

你可以用这个:

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

我试过了,效果很好。

下面的函数用于检查对象是否存在。

def exists(obj, **kwargs):
"""" if obj filtered by kwargs exist return it otherwise return None
obj : is the sql alchemy model object which existence is being checked here.
**kwargs : (username = user_name, email=user_email)
"""
db_obj = obj.query.filter_by(**kwargs).first()
if db_obj is not None:
return True
else:
return False