问题描述
||
我正在使用批量加载器从一台GAE服务器下载我的评论类型,然后上传到另一台GAE服务器。该评论类型包含大约30,000个实体。
我使用命令上传:
appcfg.py upload_data --kind=Review --filename=review.csv --application=<MY_APP_ID> --url=http://<MY_APP_ID>.appspot.com/remote_api --rps_limit=500 --bandwidth_limit=2500000 --batch_size=100
注意:整个错误很长。因此,我已将其包括在此问题的底部。
上载根本不会开始,而是在以下行停止:[INFO ] opening database: bulkloader-progress-20110611.222101.sql3
我在整个轨迹的底部看到:lambda val: _EPOCH + datetime.timedelta(microseconds=val),OverflowError: date value out of range
我怀疑这是由于在我的dateddate列中找到格式错误的日期所引起的(有关完整的Review类型,请参见下文)。
我已经尝试解决的问题
我在GAE管理门户网站中运行了GQL:“ 3”,发现约有15个实体,其publisheddate列的值为空。因此,我删除了这些内容,重新下载并尝试重新上传“评论”种类。我仍然遇到相同的错误。
我在想,因为我使用的是没有配置文件参数的上载命令,例如--config_file=bulkloader.yaml
(请参见上面的上传,我未指定--config_file
)
我依靠数据存储区统计信息来确定下载到我的review.csv文件中的内容。
现在,由于我刚删除了发布日期为null的实体,因此重新下载并立即重新上传的操作与我最初的下载和上传没有任何不同。由于数据存储区统计信息尚未更新。
我的问题
由于有30个实体,因此我不确定如何查找格式错误的实体。是否可以快速找到发布日期值错误的实体?
有人知道如何解决此问题吗?我从错误跟踪中不确定真正的问题是什么。
评论种类
我正在使用objectify3.0.jar来操纵我的GAE数据存储区。所以我的评论类型看起来像这样:
public class Review {
@Id private Long id; //This is my key property,auto generated by objectify
private String reviewlink;
private Date publisheddate;
private double rating;
private Long gameid; //to make querying easier
//ommitting getters and setters
}
整个错误
10:20:48>appcfg.py upload_data --kind=Review --filename=review.csv --application=<MY_APP_ID> --url=http://<MY_APP_ID>.appspot.com/remote_api --rps_limit=500 --bandwidth_limit=2500000 --batch_size=100
Uploading data records.
[INFO ] Logging to bulkloader-log-20110611.222101
[INFO ] Throttling transfers:
[INFO ] Bandwidth: 2500000 bytes/second
[INFO ] HTTP connections: 8/second
[INFO ] Entities inserted/fetched/modified: 500/second
[INFO ] Batch Size: 100
[INFO ] opening database: bulkloader-progress-20110611.222101.sql3
Traceback (most recent call last):
File \"/usr/local/bin/appcfg.py\",line 76,in <module>
run_file(__file__,globals())
File \"/usr/local/bin/appcfg.py\",line 72,in run_file
execfile(script_path,globals_)
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/appcfg.py\",line 3592,in <module>
main(sys.argv)
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/appcfg.py\",line 3583,in main
result = AppCfgApp(argv).Run()
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/appcfg.py\",line 2229,in Run
self.action(self)
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/appcfg.py\",line 3368,in __call__
return method()
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/appcfg.py\",line 3195,in PerformUpload
run_fn(args)
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/appcfg.py\",line 3087,in RunBulkloader
sys.exit(bulkloader.Run(arg_dict))
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/bulkloader.py\",line 4360,in Run
return _PerformBulkload(arg_dict)
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/bulkloader.py\",line 4204,in _PerformBulkload
loader.initialize(filename,loader_opts)
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/bulkloader.py\",line 2879,in initialize
self.high_id_table = self._find_high_id(self.generate_records(filename))
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/bulkloader.py\",line 2896,in _find_high_id
for values in record_generator:
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/bulkloader.py\",line 2920,in generate_records
yield datastore.Entity._FromPb(fixed_entity_proto)
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore.py\",line 958,in _FromPb
value = datastore_types.FromPropertyPb(prop)
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore_types.py\",line 1792,in FromPropertyPb
value = conversion(value)
File \"/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore_types.py\",line 1722,in <lambda>
lambda val: _EPOCH + datetime.timedelta(microseconds=val),OverflowError: date value out of range
解决方法
查找有问题的行的方法
我用来查找有问题的行的方法是使用带有配置文件的大容量加载器下载每一行,直到到达无法下载的行为止。一旦纠正了有问题的行,下载/上传就可以正常工作。
注意:实际上,它是多行,但是一旦找到第一个行,就只是用有问题的数据查找/替换其他行的问题。
我用来查找行的命令是:
appcfg.py upload_data --coinfig_file=bulkloader.yaml --kind=Review --filename=review.csv --application=<MY_APP_ID> --url=http://<MY_APP_ID>.appspot.com/remote_api --rps_limit=500 --bandwidth_limit=2500000 --batch_size=100
注意:在上面的问题中,我没有使用配置文件。在此命令上方。我正在使用配置文件。使用以下命令从数据存储区统计信息生成此配置文件:
appcfg.py create_bulkloader_config --filename=bulkloader.yaml --application=<appname> --url=http://<appname>.appspot.com/remote_api
使用配置文件的主要原因是它会下载以正确的csv文件格式设置的我的数据存储。
题?
由于某些原因,当您不使用批量加载器指定配置文件时。下载的csv太乱了,即其中包含许多随机字符。但是,将这些文件上传回数据存储区没有问题。
在上传到数据存储区时,为什么格式正确的csv文件和这些凌乱的csv文件都能工作?
有问题的行
实际的问题是publisheddate
属性的某些数据的值设置为00/00/0000(MM / DD / YYYY)。 Java将其转换为Date
,其值是0001年1月2日(星期日)(不要在值上引用我,但我记得当年是0001)。
可以将其插入GAE数据存储库中,但是,当批量加载器尝试下载或上传这些值时,它会报错:lambda val: _EPOCH + datetime.timedelta(microseconds=val),OverflowError: date value out of range
,如上所述。