关于下载 GAE High Replication Datastore 数据[实战篇]上
前言
本文部分内容谷歌官方文档并未陈述,根据谷歌文档和实战经验看来,谷歌目前对High Replication datastore的数据下载支持并不稳定,不过谷歌称在未来将会改善。
从写本文到落实本文期间,谷歌对Google Engine Launcher进行了一次升级到1.7.7.695。所以不保证本文所有内容对最新的Google Engine都适用。
[注意]谷歌关于数据上传下载的文档所针对的是Master/slave datastore,而本文是根据针对High Replication datastore而作的。因为我没有使用过Master/slave datastore,因此不知道谷歌原文针对Master/slave datastore的描述有效性如何。如果你使用Master/slave datastore,请优先参考原文,然后再参考本文。
[注意]谷歌针对Master/slave datastore给出的命令,有些在执行时并不能成功,这些针对High Replication datastore失效的命令在本文中使用红色字体进行引用。
正文
谷歌使用一个叫Bulk loader tool的东西进行数据的上传下载,要想要从谷歌的datastore上传下载数据,关键在于配置bulk loader。通过Bulk Loader传递数据时,不支持Federated(OpenID) Authentication,而且目前说来主要支持Master/slave datastore,对High Replication datastore而言,谷歌称用户可以从 High Replication datastore 获取数据,但目前不支持,如果尝试从 High Replication datastore 下载数据的话,会在管理员控制台出现 high_replication_warning error,而且不会包含最近保存的Entities。
但根据个人经验,事实上目前已经可以从 high replication datastore 下载数据,也没有出现 high_replication_warning error,但有时可以成功,有时失败,有时下载的数据格式不对,有时下载数据不完整,因此可以看出谷歌对从 high replication datastore 下载数据的支持仍不稳定。
从GAE Datastore上传或下载数据分为三个步骤:
- 开启数据传递接口remote_api:必须开启了remote_api接口才能进行数据传输,开启了接口就可以将所有数据作为一个整体进行上传下载。(不用配置bulkloader.yaml)
- 配置数据结构描述文件bulkloader.yaml:如果想下载datastore中指定的kind,并且按照xml或csv格式进行传递的话,就必须配置并使用bulkloader.yaml。
- 上传或下载数据:通过命令行,按照bulkloader.yaml中的数据格式描述来上传下载数据。
开启remote_api
Google Engine通过remote_api接口来与部署在Google Engine的App进行通讯,Google Engine允许具有合法身份的请求通过remote_api接口远程访问App datastore。
有两种配置方法来开启remote_api,使用内建指令(builtins directive)或者url指令(url directive)。
1. 使用内建指令开启remote_api
在App文件夹中,编辑app.yaml,增加以下代码:
builtins:
- remote_api: on
这个命令会引导App去 include.yaml 文件中寻找 remote_api 接口,并且将此接口映射到 /_ah/remote_api,这个url地址只有管理员才可以访问。
但谷歌没有告诉你,你的App文件夹中很可能是没有 include.yaml 文件的。因此你需要创建一个 include.yaml 文件,内容如下:
handlers: - url: /_ah/remote_api(/.*)? script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
以上配置完成之后,使用Google Engine Launcher重新部署一次,如果没有安装Launcher则可以使用以下命令进行部署更新。部署完成后就开启了remote_api。
appcfg.py update <app-directory>
2. 使用url指令开启remote_api
使用url指令的好处在于可以将remote_api映射到个性化的url,而使用内建指令时,你的访问地址必定是 /_ah/remote_api。还是编辑app.yaml文件,增加以下内容:
- url: /remote_api script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py login: admin
在第一行的url中,你可以配置你想要的url作为接口访问地址。当然,这个接口仍只有管理员可以访问。配置完成后重新部署一次应用以更新服务器端的app.yaml文件。
[注意]谷歌提醒使用个性化url访问remote_api接口时,需要提前在 /_ah/remote_api 路径下安装了 remote_api handler。因为我一开始是使用内建命令开启remote_api,因此remote_api handler可能就在这个时候就被安装了,如果你一开始使用url指令但运行失败的话,不妨先用内建指令开启一下remote_api,然后再改用url指令来个性化自己的访问地址。
3. 上传和下载所有数据
因为没有配置bulkloader.yaml,因此此时只能将所有kinds或者某一个kind下载下来,而不能按照xml或者csv进行上传或下载。这时下载的data文件只能作为数据库备份,或者将一个应用的数据库迁徙到另一个应用的数据库中而使用。并且该data不能作为本地的开发服务器使用。
若要下载所有kind,谷歌说执行以下指令:
$ appcfg.py download_data --url=http://your_app_id.appspot.com/_ah/remote_api --filename=<data-filename>
其中url中的 /_ah/remote_api 是你之前开启remote_api时所指定的映射地址,filename是下载到本地需要生成的文件名(谷歌没有限定输出的文件名,你可以自己指定,数据会被写入这个文件中。)
正如你所见以上谷歌原文被以红色字体进行引述,说明它是一条失败的命令。以上命令失败之处在于,url中的http协议应修改为https协议。如果仅是修改https协议,也不会成功,你甚至都没有连接到你的remote_api。下面是正确写法:
$ appcfg.py download_data --application=s~ifantastic-dragon --auth_domain=gmail.com --url=https://ifantastic-dragon.appspot.com/_ah/remote_api --filename=s.sql3
以上代码解释:
- download_data:下载数据,如果要上传则是upload_data。
- --application:表示需要连接的应用名称,谷歌说使用--url参数时会自动探测到application名称,所以不推荐使用--application,但是如果不使用--application参数,你很难连接上你的remote_api接口(不过我有一次没有使用--application也下载成功,所以证明GAE还很不稳定。)。[注意]在输入应用名称时格式为 s~applicationname。
- --auth_domain:当连接GAE的remote_api需要验证身份,这个参数可以让你使用谷歌帐号来访问Google App。如果不加入这个参数,在命令行中你会没有机会输入你的帐号和密码,但直接得到身份验证失败的错误提示。(我也曾经不使用这个参数成功下载过。不过最近都一直要加这个参数才行。)
- --url:请使用https代替http协议,个人经验从未使用http协议成功过。
- --filename:必须指定一个filename来接收数据,类型无所谓。
[注意]关于参数的顺序问题,虽然是命名参数,但个人经验是,按照以上所示例的顺序书写参数成功次数较多。所以建议先传入application和auth_domain,以便顺利进行身份认证。
如果要下载指定kind,可以加上--kind参数,如下:
$ appcfg.py download_data --application=s~ifantastic-dragon --auth_domain=gmail.com --url=https://ifantastic-dragon.appspot.com/_ah/remote_api --kind=Wordroot --filename=s.sql3
上传数据与下载类似,只需要将download_data修改为upload_data就可以了。
好了,关于上传和下载数据先写到这儿,下篇将介绍如何使用bulkloader来传递xml或csv。