我们希望一次性将大约30k个实体上传到数据存储区,同时还可以从与这些实体相关联的字符串创建文档。
这是为了允许对数据存储区不适合的字符串进行部分搜索。
但是,我们无法找到有关如何使用搜索API功能批量上传文档的任何资源或文档。
我们如何解决这个问题?
我们尝试使用bulkloader,它不断发出以下错误
google.appengine.ext.db.KindError: No implementation for kind 'Prototype'
这是因为我们试图上传ndb模型,但错误表明它是默认为db
我们尝试破解它并将其定义为数据库模型并上传它。这有效,数据上传到数据存储区,但post_put_hook无法正常工作
以下是代码:
#models.py
import datetime
from google.appengine.ext import db
from google.appengine.tools import bulkloader
class PrototypeE(db.Model):
#creating db Model of data
p_id=db.StringProperty(indexed=True,required=True)
p_name=db.StringProperty(required=True)
p_val=db.IntegerProperty(required=True)
p_lnk=db.StringProperty(required=True)
p_src=db.StringProperty(choices=site_list)
p_create_time=db.DateTimeProperty(auto_now_add=True)
p_update_time=db.DateTimeProperty(auto_now=True)
p_gen=db.StringProperty(choices=gen_list)
p_img=db.StringProperty()
p_cat=db.StringProperty()
p_brd=db.StringProperty()
p_keys=db.StringProperty()
def _post_put_hook(self,Future):
doc_key=Future.get_result()
doc_id=doc_key.id()
doc= search.Document(doc_id=unicode(doc_id),
fields=[
search.TextField(name="keywords",value=self.p_keys),
search.NumberField(name="value",value=self.p_price)
]) #document
logging.info(doc)
try:
index=search.Index(name="Store_Doc")
index.put(doc) #putting data into document
except search.Error:
logging.exception('Doc put failed')
装载机:
#proto_loader.py
import datetime
from google.appengine.ext import ndb
from google.appengine.tools import bulkloader
import models
class ProtoLoader(bulkloader.Loader):
def __init__(self):
bulkloader.Loader.__init__(self, 'PrototypeE',
[('p_id', str),
('p_name', str),
('p_val', int),
('p_lnk', str),
('p_src',str),
('p_gen',str),
('p_img',str),
('p_cat',str),
('p_brd',str),
('p_keys',str)
])
loaders = [ProtoLoader]
成功将数据上传到数据存储区,但是没有调用钩子,也没有创建文档。
我们是否需要编辑bulkloader文件来解决此问题?
更新:如前所述,我们尝试混合ndb和db的原因是,在将类定义为ndb.Model时,我们得到以下错误
Traceback (most recent call last):
File "appcfg.py", line 126, in <module>
run_file(__file__, globals())
File "appcfg.py", line 122, in run_file
execfile(_PATHS.script_file(script_name), globals_)
File "/home/stw/Google/google_appengine/google/appengine/tools/appcfg.py", line 5220, in <module>
main(sys.argv)
File "/home/stw/Google/google_appengine/google/appengine/tools/appcfg.py", line 5211, in main
result = AppCfgApp(argv).Run()
File "/home/stw/Google/google_appengine/google/appengine/tools/appcfg.py", line 2886, in Run
self.action(self)
File "/home/stw/Google/google_appengine/google/appengine/tools/appcfg.py", line 4890, in __call__
return method()
File "/home/stw/Google/google_appengine/google/appengine/tools/appcfg.py", line 4693, in PerformUpload
run_fn(args)
File "/home/stw/Google/google_appengine/google/appengine/tools/appcfg.py", line 4574, in RunBulkloader
sys.exit(bulkloader.Run(arg_dict))
File "/home/stw/Google/google_appengine/google/appengine/tools/bulkloader.py", line 4408, in Run
return _PerformBulkload(arg_dict)
File "/home/stw/Google/google_appengine/google/appengine/tools/bulkloader.py", line 4219, in _PerformBulkload
LoadConfig(config_file)
File "/home/stw/Google/google_appengine/google/appengine/tools/bulkloader.py", line 3886, in LoadConfig
Loader.RegisterLoader(cls())
File "proto_loader.py", line 40, in __init__
('p_keys',str)
File "/home/stw/Google/google_appengine/google/appengine/tools/bulkloader.py", line 2687, in __init__
GetImplementationClass(kind)
File "/home/stw/Google/google_appengine/google/appengine/tools/bulkloader.py", line 957, in GetImplementationClass
implementation_class = db.class_for_kind(kind_or_class_key)
File "/home/stw/Google/google_appengine/google/appengine/ext/db/__init__.py", line 296, in class_for_kind
raise KindError('No implementation for kind \'%s\'' % kind)
google.appengine.ext.db.KindError: No implementation for kind 'PrototypeE'
如错误所示,bulkloader假定使用db类并使用db.class_for_kind进行检查,这在使用ndb时会导致错误