如何使用远程API重置数据存储模型的propertytype

2024-10-03 23:27:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我在现有的数据存储中有一个模型。看起来像这样:

class SomeKind(db.Model):
  name = db.StringProperty(required=True)
  someField = db.BlobProperty(required=True)

数据存储中大约有20000多个此类实体 现在我想重组一下,让它变成这样:

^{pr2}$

我想我必须

  1. 在数据存储中循环以删除现有的“someField”数据。从模型.py在
  2. 删除属性
  3. 使用新定义将属性添加到模型.py在

我在(1)处遇到了问题,我想用远程API删除现有属性:

import sys, time, urllib2

sys.path.append("gae/paths")
...
sys.path.append("myapp/path")
from google.appengine.ext import db
from google.appengine.api import memcache
from google.appengine.ext.remote_api import remote_api_stub
from models import *

def tryPut(db, set, tryLimit=10, seconds=5, trying=1):
  try:
    db.put(set)
    return True
  except urllib2.HTTPError:
    if trying <= tryLimit:
      print "retry (%d of %d) in 5 seconds" % (trying, tryLimit)
      time.sleep(5)
      tryPut(db, set, seconds, trying+1)
    else:
      print urllib2.HTTPError
      sys.exit()

def main():

    remote_api_stub.ConfigureRemoteDatastore(None, 
      '/remote_api', my_auth_func, 'myapp.appspot.com')
    q = db.GqlQuery("SELECT * FROM SomeKind")
    last_cursor = memcache.get('SomeKind/update')

    if last_cursor:
        q.with_cursor(last_cursor)

    set = q.fetch(100)

    while len(set) != 0:
      for someKind in set:
        print someKind.name

        # this doesn't work
        delattr(someKind, "someField")

        # this doesn't work either
        del someKind.someField

      print "update to Google"
      if tryPut(db, set):
        cursor = q.cursor()
        memcache.set('SomeKind/update', cursor)

if __name__ == "__main__":
  main()

我在我的机器上运行这个。 问题是,无论使用哪种方法,此脚本都会引发错误:

Traceback (most recent call last):
File "./query.py", line 91, in <module>
  main()
File "./query.py", line 66, in main
  del someKind.someField
AttributeError: __delete__

文档(http://code.google.com/intl/en/appengine/articles/update_schema.html)说了类似“使用delattr删除过时属性,然后保存实体”的内容。但从来没有这样的例子。在

我该怎么做? 我的脚步正确吗? 我是怎么删除属性的?在


Tags: 数据frompyimportapidb属性main
2条回答

不能从模型中删除属性-每个模型实例都有相同的属性集。^然而,{a1}允许您拥有动态属性。在

最简单的方法可能是:

  1. 更改模型类以扩展扩展数据库而不是数据库模型在
  2. 将新属性添加到model类(如果希望在数据存储中为它指定一个与Python中访问它的名称不同的名称,请使用'name'关键字参数),然后删除旧的属性。在
  3. 使用mapreduce API遍历每个实体,调用“del我的模型.oldprop,并根据需要设置新属性。在
  4. 再次更新模型定义,将其设置回“扩展”数据库模型. 在

像这样使用

class News(db.Expando):
    title = db.StringProperty()
    #category = db.TextProperty()     -> removed property
    tags = db.StringProperty()
    content_short = db.TextProperty()
    content_long = db.TextProperty()
    date = db.DateTimeProperty()
    views = db.IntegerProperty(default=0)

以及

^{pr2}$

完整代码在这里-http://appengine4dummies.blogspot.com/2012/01/text-that-matters-deleting-appengine.html

相关问题 更多 >