db.put模型可以不先db.getting它们吗?

时间:2010-05-08 05:08:41

标签: python google-app-engine

我尝试做类似

的事情

ss = Screenshot(key=db.Key.from_path('myapp_screenshot', 123), name='flowers') db.put([ss, ...])

它似乎适用于我的dev_appserver,但在现场我得到了这个追溯:

  

05-07 09:50 PM 19.964文件“/base/data/home/apps/quixeydev3/12.341796548761906563/common/appenginepatch/appenginepatcher/patch.py​​”,   第600行,在put   E 05-07 09:50 PM 19.964 result = old_db_put(models,* args,** kwargs)   GAE bug实际上非常小。这似乎是因为我打电话给l   E 05-07 09:50 PM 19.964文件“/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py”,   第1278行,在put   E 05-07 09:50 PM 19.964 keys = datastore.Put(entities,rpc = rpc)

     

E 05-07 09:50 PM 19.964文件“/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py”,   第284行,在Put中   E 05-07 09:50 PM 19.965 raise _ToDatastoreError(err)

     

E 05-07 09:50 PM 19.965 InternalError:新实体或指数
  你试图插入已存在

我碰巧只知道我要更新的现有屏幕截图实体的ID;这就是我手动构建其密钥的原因。我做错了吗?

更新:我将此归档为Google App Engine issue 3209

更新2:它看起来像ike db.put([ss,ss2,ss]),即当列表引用相同模型两次时调用失败。

更新3:好的,我想我终于知道这里发生了什么,我正在更新这个问题,因为现在它是“你尝试过的新实体或索引的唯一Google结果插入已存在“。

当数据存储区在同一个远程过程调用中尝试对同一个实体键进行两次BigTable行写操作时,似乎会出现此InternalError。如果您手动为两个实体提供相同的密钥,或者如果您在不指定密钥的情况下放置()两个新实体,并且同一ID同时分配给两个实体,则会发生这种情况。在后一种情况下,解决方案是使用db.allocate_ids()。

3 个答案:

答案 0 :(得分:2)

这是一个错误 - 您应该能够完全按照您的描述进行操作。作为解决方法,我们可以修复它,使用键名(即使它们是数字)而不是ID应该可以正常工作。

答案 1 :(得分:0)

我相当肯定你可以ss.save()

基本上你的数据库实体已经存在,因此您只需保存对它的更改,db.put用于添加新实体。希望有所帮助。

显然这是一个错误。我对它进行了更多的研究,并找到了一些实体组的参考,这些组允许在单个事务中进行多个实体修改,但是它们声明它们对查询的速度没有显着影响。

答案 2 :(得分:0)

如果您只想更新一个实体,可以使用Model.put()代替db.put()。这将创建实体(如果实体尚不存在),或者如果实体更新它。

所以你会做ss.put()