Python 2.7 将带有dict属性的JSON写入Google云数据存储
使用ApacheBeam(Python2.7SDK),我试图将JSON文件作为实体写入Google云数据存储 示例JSON:Python 2.7 将带有dict属性的JSON写入Google云数据存储,python-2.7,google-cloud-datastore,google-cloud-dataflow,Python 2.7,Google Cloud Datastore,Google Cloud Dataflow,使用ApacheBeam(Python2.7SDK),我试图将JSON文件作为实体写入Google云数据存储 示例JSON: { "CustId": "005056B81111", "Name": "John Smith", "Phone": "827188111", "Email": "john@xxx.com", "addresses": [ {"type": "Billing", "streetAddress": "Street 7", "city": "Malmo", "po
{
"CustId": "005056B81111",
"Name": "John Smith",
"Phone": "827188111",
"Email": "john@xxx.com",
"addresses": [
{"type": "Billing", "streetAddress": "Street 7", "city": "Malmo", "postalCode": "CR0 4UZ"},
{"type": "Shipping", "streetAddress": "Street 6", "city": "Stockholm", "postalCode": "YYT IKO"}
]
}
我编写了一个Apache Beam管道,主要包括3个步骤
class CreateEntities(beam.DoFn):
def process(self, element):
element = element.encode('ascii','ignore')
element = json.loads(element)
Id = element.pop('CustId')
entity = entity_pb2.Entity()
datastore_helper.add_key_path(entity.key, 'CustomerDF', Id)
datastore_helper.add_properties(entity, element)
return [entity]
这适用于基本属性。然而,由于地址本身是一个dict对象,所以它失败了。
我读过一篇类似的文章
但是,没有获得转换dict->entity的确切代码
尝试在下面将地址元素设置为实体,但不起作用
element['addresses'] = entity_pb2.Entity()
其他参考资料:
ndb.StructuredProperty
s显示在数据流中,键被展平,对于重复的结构化属性,结构化属性对象中的每个单独属性都成为一个数组。所以我认为你需要这样写:
datastore_helper.add_properties(entity, {
...
"addresses.type": ["Billing", "Shipping"],
"addresses.streetAddress": ["Street 7", "Street 6"],
"addresses.city": ["Malmo", "Stockholm"],
"addresses.postalCode": ["CR0 4UZ", "YYT IKO"],
})
或者,如果您试图将其另存为ndb.json属性,则可以执行以下操作:
datastore_helper.add_properties(entity, {
...
"addresses": json.dumps(element['addresses']),
})
我知道这是一个老问题,但我有一个类似的问题(尽管是Python3.6和NDB),并编写了一个函数将
dict
中的所有dict
转换为实体。这将使用递归遍历所有节点,并根据需要进行转换:
def dict_to_entity(data):
# the data can be a dict or a list, and they are iterated over differently
# also create a new object to store the child objects
if type(data) == dict:
childiterator = data.items()
new_data = {}
elif type(data) == list:
childiterator = enumerate(data)
new_data = []
else:
return
for i, child in childiterator:
# if the child is a dict or a list, continue drilling...
if type(child) in [dict, list]:
new_child = dict_to_entity(child)
else:
new_child = child
# add the child data to the new object
if type(data) == dict:
new_data[i] = new_child
else:
new_data.append(new_child)
# convert the new object to Entity if needed
if type(data) == dict:
child_entity = datastore.Entity()
child_entity.update(new_data)
return child_entity
else:
return new_data
谢谢@Alex。我现在正在尝试使用NDB。为此,我使用命令“from google.appengine.ext import NDB”导入NDB,当我尝试执行“pip install google.appengine.ext”时,它失败地说“找不到满足要求的版本google.appengine.ext(from versions:)找不到与google.appengine.ext“I did,”gcloud components install app engine python“匹配的发行版,但仍然存在相同的错误。Oh ndb只能从app engine standard中使用。但是我假设你有一个应用程序引擎应用程序,你正在尝试将这些记录发送到我没有使用AppEngine。我正在使用Python(2.7)SDK运行ApacheBeam管道。这个管道从云存储读取.JSON文件并将其写入云数据存储。所以从您的回复来看,ndb似乎无法使用。对,但一旦这些记录进入数据存储。您计划如何读取/使用它们?是的,我们有一个AppEngine来访问数据存储中的记录。它是使用Node.js构建的。那么,我可以尝试用Apache Beam解决这个问题吗?