Python AppEngine(或者Django)中是否有名为insert_或_update的快捷方式?为什么不呢?

Python AppEngine(或者Django)中是否有名为insert_或_update的快捷方式?为什么不呢?,python,django,google-app-engine,insert-update,Python,Django,Google App Engine,Insert Update,我多次重复这种模式:(我想这不是很常见吗?) 谷歌应用程序引擎 # Insert if object doesn't exist, Otherwise Update Object obj = get_or_insert('123', title='Hello World') obj.title = 'Hello World' obj.puts() Django # Insert if object doesn't exist, Otherwise Update Object obj, crea

我多次重复这种模式:(我想这不是很常见吗?)

谷歌应用程序引擎

# Insert if object doesn't exist, Otherwise Update Object
obj = get_or_insert('123', title='Hello World')
obj.title = 'Hello World'
obj.puts()
Django

# Insert if object doesn't exist, Otherwise Update Object
obj, created = Model.objects.get_or_create(id='123', 
                   defaults={'title':'Hello World'}
if not created:
    obj.title = 'Hello World'
    obj.save()
如果I可以只需调用
insert\u或\u update
,那就好了。不是吗?e、 g:

# AppEngine
obj = insert_or_update('123', title='Hello World')

# Django
obj = Model.objects.insert_or_update(id='123', defaults={'title': 'Hello World'})
更新 回到appengine,我找到了这个
get\u或\u insert
方法的代码片段。如下所示:

def txn(key_name, **kwds):
    entity = Story.get_by_key_name(key_name, parent=kwds.get('parent'))
    if entity is None:
        entity = Story(key_name=key_name, **kwds)
        entity.put()
    return entity

def get_or_insert(key_name, **kwargs):
    return db.run_in_transaction(txn, key_name, **kwargs)

get_or_insert('some key', title="The Three Little Pigs")
obj, created = Model.objects.get_or_create(foo='alpha', bar='beta' 
               defaults={'title':'Hello World'})
我想知道为什么appengine和django中都没有创建
insert\u或\u update
方法

应用程序引擎解决方案 Django溶液
如果我正确理解了问题:

obj, created = Model.objects.get_or_create(id='123', 
               defaults={'title':'Hello World'})
上述内容应替换为以下内容:

def txn(key_name, **kwds):
    entity = Story.get_by_key_name(key_name, parent=kwds.get('parent'))
    if entity is None:
        entity = Story(key_name=key_name, **kwds)
        entity.put()
    return entity

def get_or_insert(key_name, **kwargs):
    return db.run_in_transaction(txn, key_name, **kwargs)

get_or_insert('some key', title="The Three Little Pigs")
obj, created = Model.objects.get_or_create(foo='alpha', bar='beta' 
               defaults={'title':'Hello World'})

其中foo和bar是模型中的字段。这解决了django的重复问题。对appengine不确定。这可能不像你想象的那么普遍。就我个人而言,我发现自己不必经常这样做,而且当我这样做时,它只比您建议的
insert\u或\u update
方法长两三行,这还不足以让我大声呼喊这个特性,也不足以激励我自己添加它。尽管过去我在重复密钥更新中使用了MySQL的
INSERT…

我自己也有过几次这样的经历,就在几周前,我还在想为什么Django在M2M关系上没有一个
toggle
方法……我最后做了一个:

编辑 Django 1.7看起来将具有这个“UPSERT”功能,

Django (来自Django官方文件)

Django 1.7版本中的新增功能

使用给定的
kwargs
更新对象的便捷方法,必要时创建新对象。
默认值
是用于更新对象的(字段、值)对字典

返回
(object,created)
的元组,其中
object
是已创建或更新的对象,
created
是指定是否创建新对象的布尔值

update\u或\u create
方法尝试根据给定的
kwargs
从数据库中获取对象。如果找到匹配项,它将更新在
默认值
字典中传递的字段

这是通往样板代码的捷径。例如:

try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
    for key, value in updated_values.iteritems():
        setattr(obj, key, value)
    obj.save()
except Person.DoesNotExist:
    updated_values.update({'first_name': 'John', 'last_name': 'Lennon'})
    obj = Person(**updated_values)
    obj.save()
随着模型中字段数量的增加,这种模式变得相当笨拙。可以使用
update\u或\u create()
重写上述示例,如下所示:

obj, created = Person.objects.update_or_create(
    first_name='John', last_name='Lennon', defaults=updated_values)
有关如何解析kwargs中传递的名称的详细说明,请参阅

如上文中所述,此方法容易出现争用情况,如果不在数据库级别强制执行唯一性,则可能导致同时插入多行

阿彭金
还没有那么幸运,正如Matt之前提到的,它可能不是一个常见的用例。也许在AppEngine中,这种用例并不多

对不起,我想你误解了我的问题。使用当前的答案,您将获得所提供参数的对象。object.title可能不是Hello World,因此我还想用标题Hello World更新该对象。因此,如果您已经拥有该对象,请将标题更新为Hello World。如果没有对象,请创建标题为Hello World的对象。将其放在一行快捷方式方法中,即Model.objects.insert_或_update(foo='alpha',bar='beta',defaults={'title':'Hello World'});但我在想,为什么没有这样的方法,这不是常见的用例吗?#您的代码需要一些额外的行,才能按照我的要求工作。;如果不是obj:obj.title=“Hello World;obj.save();嗯……这是有道理的,……无论如何,这是M2M的一个有趣的切换功能。+1:-你说的是一个返回我相信的值的UPSERT操作。Django完全不支持这样的函数。最近有一个提交与这个问题有关,@MattDeacalionStevens,最后。那将在Django 1.7上,:-)是的……一个whi我还想去,但你说得对。:-)