[英]How to copy datastore entities between namespaces
I want to copy all the data in one namespace, say www.mysite.com, to another namespace, say nightly.latest.mysite.appspot.com. 我想将一个名称空间中的所有数据(例如www.mysite.com)复制到另一个名称空间,比如nightly.latest.mysite.appspot.com。 What's the best way to do this?
最好的方法是什么?
The example namespaces are not random: they're the namespaces that are set by a NamespaceFilter for the given domains that serve the app. 示例命名空间不是随机的:它们是NamespaceFilter为服务应用程序的给定域设置的命名空间。
I want to be able to pull all the 'production' data into a 'non-production' namespace for testing. 我希望能够将所有“生产”数据拉入“非生产”命名空间进行测试。
Namespace is the part of the Key. 命名空间是Key的一部分。 So you can't change or copy all data from one namespace to another.
因此您无法将所有数据从一个名称空间更改或复制到另一个名称空间 As I understand all you can do is to fetch all objects from one namespace and create NEW objects with the same properties in another namespace.
据我所知,你所能做的就是从一个命名空间中获取所有对象,并在另一个命名空间中创建具有相同属性的NEW对象。
I'm using appengine-mapreduce for this. 我正在使用appengine-mapreduce 。 I won't walk through setting it up in detail.
我不会详细介绍它。 You can read the getting started guides for that information.
您可以阅读该信息的入门指南 。
Right now you have to enter each class name to be copied. 现在你必须输入要复制的每个类名。 TODO is figuring out how to loop over all the __Stat_Kind__ results programmatically so each kind/class doesn't have to be specified separately.
TODO正在计算如何以编程方式遍历所有__Stat_Kind__结果,因此不必单独指定每种类/类。
import java.util.logging.Logger;
import org.apache.hadoop.io.NullWritable;
import com.google.appengine.api.NamespaceManager;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.tools.mapreduce.AppEngineMapper;
public class DatastoreCopyMapper extends
AppEngineMapper<Key, Entity, NullWritable, NullWritable> {
private static final Logger log = Logger
.getLogger(DatastoreCopyMapper.class.getName());
private static String destination;
public DatastoreCopyMapper() {
}
@Override
public void taskSetup(Context context) {
log.warning("Doing per-task setup");
destination = context.getConfiguration().get("destination");
log.warning("destination: " + destination);
}
@Override
public void map(Key key, Entity value, Context context) {
NamespaceManager.set(destination);
String name = key.getName();
long id = key.getId();
Key destinationKey = null;
if (name != null) {
destinationKey = KeyFactory.createKey(key.getKind(), name);
} else if (id != 0) {
destinationKey = KeyFactory.createKey(key.getKind(), id);
}
Entity destinationEntity = new Entity(destinationKey);
destinationEntity.setPropertiesFrom(value);
DatastoreService datastore = DatastoreServiceFactory
.getDatastoreService();
datastore.put(destinationEntity);
}
}
mapreduce.xml mapreduce.xml
<configurations>
<configuration name="Copy between namespaces">
<property>
<name>mapreduce.map.class</name>
<value>com.mysite.server.DatastoreCopyMapper</value>
</property>
<property>
<name>mapreduce.inputformat.class</name>
<value>com.google.appengine.tools.mapreduce.DatastoreInputFormat</value>
</property>
<property>
<name human="Entity Kind to Map Over">mapreduce.mapper.inputformat.datastoreinputformat.entitykind</name>
<value template="optional">User</value>
</property>
<property>
<name human="Destination Namespace">mapreduce.mapper.inputformat.datastoreinputformat.destination</name>
<value template="optional">dev.mysite.com</value>
</property>
</configuration>
</configurations>
Unfortunately there is currently no automated way to do this. 不幸的是,目前没有自动化的方法来做到这一点。
You are going to have to loop over all of your data and re-save it to the new namespace. 您将不得不遍历所有数据并将其重新保存到新的命名空间。 You can read about Java and namespaces, in the multitenancy docs.
您可以在多租户文档中阅读有关Java和名称空间的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.