如何优雅地检查对象/实例/变量是否存在并同时在Python中赋值?

80 投票
9 回答
76743 浏览
提问于 2025-04-16 20:53

我正在使用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,也适用于其他类似的场景。

我闭上眼睛,点击“发布问题”,然后等待聪明的人和热爱Python的人来找我,因为我问了一个可能不太合适的问题 ;-)

9 个回答

14

把它放在一个函数里(这个想法是从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)

尽量把你经常用的东西封装起来(把它们放到函数或类里)

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

编辑:强调一下

26

这个问题很早以前就有人问过了,但为了将来来访的人,这里有一个更简洁的方法来检查。

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

你想要执行一个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()

撰写回答