我认为我的问题类似于:BulkLoader -export_transform或https://stackoverflow.com/questions/3220911/gae-datastore-export-transform
基本上,我正在使用bulkloader来备份和恢复我创建的实体。 测试我正在使用“Game”类型并将其输出到名为game.csv的csv文件。
这是我经历的过程:
使用以下方法将游戏类型下载到game.csv:
appcfg.py download_data --config_file = bulkloader.yaml --kind = Game --filename = game.csv --application = MyAppId --url = http://MyAppId.appspot.com/remote_api --rps_limit = 500 --bandwidth_limit = 2500000 --batch_size = 100
删除所有游戏实体。然后我检查了我的应用程序的管理门户数据存储区查看器选项卡,我发现我的数据存储中没有更多实体。
使用game.csv上传游戏种类(使用 download_data 命令,但 upload_data ):
appcfg.py upload_data --config_file = bulkloader.yaml --kind = Game --filename = game.csv --application = MyAppId --url = http://MyAppId.appspot.com/remote_api --rps_limit = 500 --bandwidth_limit = 2500000 --batch_size = 100
运行一个通过'name'检索实体的servlet(这是下面Game.java中显示的属性)。
发生以下错误:
Uncaught exception from servlet
java.lang.IllegalStateException: Loaded Entity has name but com.example.app.model.Game has no String @Id
at com.googlecode.objectify.impl.ConcreteEntityMetadata.setKey(ConcreteEntityMetadata.java:343)
at com.googlecode.objectify.impl.ConcreteEntityMetadata.toObject(ConcreteEntityMetadata.java:210)
at com.googlecode.objectify.impl.QueryImpl$ToObjectIterator.translate(QueryImpl.java:640)
at com.googlecode.objectify.impl.QueryImpl$ToObjectIterator.translate(QueryImpl.java:629)
at com.googlecode.objectify.util.TranslatingIterator.next(TranslatingIterator.java:35)
at com.googlecode.objectify.impl.QueryImpl.list(QueryImpl.java:470)
我怀疑它与我的 bulkloader.yaml 文件无法正确配置__key__
属性有关。所以我在下面发布了它:
- import: google.appengine.ext.bulkload.transform
- import: google.appengine.ext.bulkload.bulkloader_wizard
- import: google.appengine.ext.db
- import: google.appengine.api.datastore
- import: google.appengine.api.users
transformers:
- kind: Game
connector: csv
connector_options:
# TODO: Add connector options here--these are specific to each connector.
property_map:
- property: __key__
external_name: key
export_transform: transform.key_id_or_name_as_string
- property: __scatter__
#external_name: __scatter__
# Type: ShortBlob Stats: 56 properties of this type in this kind.
- property: genre
external_name: genre
# Type: String Stats: 6639 properties of this type in this kind.
- property: name
external_name: name
# Type: String Stats: 6639 properties of this type in this kind.
- property: releasedate
external_name: releasedate
# Type: Date/Time Stats: 6548 properties of this type in this kind.
import_transform: transform.import_date_time('%Y-%m-%dT%H:%M:%S')
export_transform: transform.export_date_time('%Y-%m-%dT%H:%M:%S')
在删除和上传数据之前,“Game”类型(在应用管理门户的数据存储区查看器标签中)显示ID/NAME
列,其超链接看起来像<对于每个有权行,strong> ID = 12345 , ID = 67890 ....
上传后,datastire查看器会显示ID/NAME
列,其中的超链接看起来像 NAME = 12345 , NAME = 67890 ...对于每个有权行
我实际上已将问题发布在https://groups.google.com/forum/?hl=en#!topic/objectify-appengine/FFuB2Onfnzc上,但我们不知道在上传数据时避免将__key__
属性转换为字符串的语法。
Jeff(Objectify3.0的创建者)说:
错误消息表明数据存储区中的数据为String名称 key,但你的Game实体有一个数字Long @Id。我真的不知道 批量加载器的语法,但最可疑的行是这一行:
export_transform: transform.key_id_or_name_as_string
看起来您在这里将所有数字ID转换为字符串, 这将是你的问题。将它们保留为数字。
我已尝试删除export_transform: transform.key_id_or_name_as_string
,但在下载时,csv文件为空。
也许解决方法是避免使用--config_file
参数和 bulkloader.yaml 文件,只是让批量加载程序下载/上传数据而不进行任何转换?
我正在使用objectify3.0.jar来操纵我的GAE数据存储区。所以我的游戏类似:
public class Game {
@Id private Long id; //This is my key property, auto generated by objectify
private String name;
private String genre;
private Date releasedate;
//ommitting getters and setters
}
答案 0 :(得分:1)
我做了一些实验,我相信我有解决方案。
我实际上从另一个stackoverflow帖子中得到了这个想法:Using Java Google App Engine bulkloader to download entire datastore to one csv file
修复方法是避免使用--config_file
和bulkloader.yaml
。
我使用以下内容将每种类型下载到单个csv文件中:
appcfg.py download_data --filename=backup.csv --application=MyAppId --url=http://MyAppId.appspot.com/remote_api --rps_limit=500 --bandwidth_limit=2500000 --batch_size=100
我使用以下内容将单个csv文件上传回数据存储区:
appcfg.py upload_data --filename=backup.csv --application=MyAppId --url=http://MyAppId.appspot.com/remote_api --rps_limit=500 --bandwidth_limit=2500000 --batch_size=100
它们是相同的命令,但只交换download_data
和upload_data
。
这个想法只是让appcfg下载并上传所有实体(不是特定类型),即不使用任何导出或导入转换。
答案 1 :(得分:0)
要避免在导入时从密钥中的Id(整数)转换为Name,请查看以下帖子:
Bulkloader: How to define the transform.create_foreign_key() as int?