使用 java google app enginebulkloader.yaml 通过 __key__ 上的 export_transform 上传数据将 ID/NAME 列从 id(长)更改为 name(字符串)

发布于 2024-11-07 13:44:39 字数 4728 浏览 6 评论 0原文

我认为我的问题类似于: BulkLoader -export_transformhttps://stackoverflow.com/questions/3220911/gae-datastore-export-transform

基本上,我使用bulkloader来备份和恢复我创建的实体。 为了测试,我使用“Game”类型并将其输出到名为 game.csv 的 csv 文件。

这是我经历的过程:

  1. 使用以下方法将游戏类型下载到 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

  2. 删除所有游戏实体。然后,我检查了应用程序的管理门户数据存储查看器选项卡,发现数据存储中没有更多实体。

  3. 使用创建的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

  4. 运行一个按“名称”检索实体的 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')

在删除和上传数据之前,“游戏” 类型(在应用管理门户的数据存储查看器选项卡内)显示 ID/NAME< /code> 列,每个实体行都有类似于 ID=12345ID=67890 ... 的超链接。

上传后,datastire 查看器会显示 ID/NAME 列,其中包含类似于 NAME=12345NAME=67890 ... 的超链接。实体行。


可能的原因?

我实际上已经在 https:/ 上发布了我的问题/groups.google.com/forum/?hl=en#!topic/objectify-appengine/FFuB2Onfnzc,但我们不知道在以下情况下避免将 __key__ 属性转换为字符串的语法:上传回数据。

Jeff(Objectify3.0 的创建者)说:

错误消息表明数据存储中的数据为字符串名称 键,但您的游戏实体有一个数字 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 文件,而只是让bulkloader下载/上传数据而不进行任何转换?


额外信息,以防可能相关

我正在使用 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 
}

I think my question is similar to: BulkLoader -export_transform OR https://stackoverflow.com/questions/3220911/gae-datastore-export-transform

Basically, I'm using the bulkloader to backup and restore entities that I've created.
To test I'm using the "Game" kind and outputting it to a csv file called game.csv.

This is the process I go through:

  1. Download the game kind to game.csv using:

    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

  2. Delete all game entities. I then checked the my app's admin portal datastore viewer tab and I see that there are no more entities in my data store.

  3. Upload the game kind using the game.csv created using (command is the same as download_data but with 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

  4. Run a servlet that retrieves an entity by 'name' (this is the property shown in Game.java below).

The following error occurs:

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)

I suspect it has something to do with my bulkloader.yaml file not being configure correct for the __key__ property. So I've posted it below:

- 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')

Prior to the deletion and upload of data, the "Game" kind (within the datastore viewer tab of the app's admin portal) shows the ID/NAME column with hyperlinks that look like ID=12345, ID=67890 ... for each entitiy row.

After the upload the datastire viewer shows the ID/NAME column with hyperlinks that look like NAME=12345, NAME=67890 ... for each entitiy row.


Possible cause?

I've actually posted my question on, https://groups.google.com/forum/?hl=en#!topic/objectify-appengine/FFuB2Onfnzc but we don't know the syntax to avoid transforming the __key__ property to string when uploading back the data.

Jeff (creator of Objectify3.0) says:

The error message says that the data in the datastore as a String name
key, but your Game entity has a numeric Long @Id. I don't really know
the syntax for the bulk loader, but the most suspect line is this one:

export_transform: transform.key_id_or_name_as_string

It looks like you are converting all numeric ids to strings here,
which would be your problem. Leave them as numbers.

I've tried removing the export_transform: transform.key_id_or_name_as_string but when I do the download the csv file is empty.

Maybe a solution is to avoid using the --config_file parameter and bulkloader.yaml file and just let the bulkloader download/upload the data without any transformations?


Extra information incase it might be relevant

I'm using the objectify3.0.jar to manipulate my GAE datastore. So my Game kind looks like this:

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 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苍暮颜 2024-11-14 13:44:39

我做了一些实验,我相信我有解决方案。

我实际上是从我问的另一篇 stackoverflow 帖子中得到这个想法的: 使用 Java Google App Engine 批量加载程序将整个数据存储区下载到一个 csv 文件

修复方法是避免使用 --config_filebulkloader.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_dataupload_data< /code> 交换了。

这个想法只是让 appcfg 下载和上传所有实体(不是特定的),即不使用任何导出或导入转换。

I did some experiements and I believe I have the solution.

I actually got the idea from another stackoverflow post I asked: Using Java Google App Engine bulkloader to download entire datastore to one csv file

The fix is to avoid using the --config_file and bulkloader.yaml.

I used the following to download every kind to a single csv file:

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

I used the following to upload the single csv file back to the datastore:

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

They are the same commands but just download_data and upload_data swapped around.

The idea is just to let appcfg download and upload all entities (not being kind specific) i.e. not using any export or import transformations.

忆梦 2024-11-14 13:44:39

为了避免在导入时将键中的 Id(整数)转换为 Name,请查看以下帖子:

Bulkloader:如何将transform.create_foreign_key()定义为int?

To avoid conversion from Id (Integer) to Name in the key at import time, have a look at the following post:

Bulkloader: How to define the transform.create_foreign_key() as int?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文