更新:根据Ivan Mainetti的建议,我在github上发布了一个问题。如果你想权衡一下,那就是:https://github.com/orientechnologies/orientdb/issues/6757
我正在开发一个基于OrienDB的数据库,并使用python接口。我有相当好的运气,但我遇到了一个问题,似乎是司机的(pyorient)书呆子在处理某些unicode字符。
我上传到数据库的数据结构如下所示:
new_Node = {'@Nodes':
{
"Abs_Address":Ono.absolute_address,
'Content':Ono.content,
'Heading':Ono.heading,
'Type':Ono.type,
'Value':Ono.value
}
}我已经在OrientDB / pyorient上无懈可击地创建了数百条记录。然而,我认为这个问题不一定是pyorient特定的问题,因为我认为它在特定记录上失败的原因是因为Ono.absolute_address元素有一个unicode字符,pyorient不知何故被它卡住了。
我要创建的记录的Abs_address为/u/c/2/a1-2,但是当我将该值传递给上面的数据结构时,我得到的节点如下:
{'@Nodes': {'Content': '', 'Abs_Address': u'/u/c/2/a1\u20132', 'Type': 'section', 'Heading': ' Transferred', 'Value': u'1\u20132'}}我想不知何故我的问题是python混合了unicode和ascii字符串/字符?我是python的新手,没有声明类型,所以我希望这不是pyorient perse的问题,因为new_Node对象不能输出格式正确的字符串...?或者这是pyorient不喜欢unicode的一个实例?在这件事上我简直要抓狂了。任何帮助都是非常感谢的。
如果错误来自pyorient而不是某种文本编码,这里是pyorient的相关信息。我使用以下代码创建记录:
rec_position = self.pyo_client.record_create(14, new_Node)这就是我得到的错误:
com.orientechnologies.orient.core.storage.ORecordDuplicatedException - Cannot index record Nodes{Content:,Abs_Address:null,Type:section,Heading: Transferred,Value:null}: found duplicated key 'null' in index 'Nodes.Abs_Address' previously assigned to the record #14:558这个错误很奇怪,因为它表明后端数据库正在为该地址获取一个空对象。显然,它确实为这个“地址”创建了一个条目,但这不是我想要它做的事情。我不知道为什么带有unicode的地址字符串在数据库中显示为null ...我可以使用输入到new_Node数据结构中的字符串通过orientDB studio创建它……但是我不能使用python做同样的事情。
有人来帮忙吗?
编辑:
多亏了Laurent,我将问题缩小到与unicode对象和pyorient有关。只要我传递的变量是unicode类型,pyorient适配器就会向OrientDB数据库发送一个空值。我确定导致问题的值是ndash符号,Laurent使用以下代码帮助我将其替换为减号
.replace(u"\u2013",u"-")然而,当我这样做时,pyorient获取unicode对象,然后将其作为空值传递……这真是不太好。我可以通过使用str(...)重新转换字符串来解决这个问题这似乎解决了我眼前的问题:
str(Ono.absolute_address.replace(u"\u2013",u"-"))。问题是,我知道我的数据库数据中会有符号和其他不寻常的字符。我知道数据库支持unicode字符串,因为我可以手动添加它们,或者使用SQL语法来做我不能通过pyorient和python做的事情。我假设这是一个危险的选角问题,但我真的不确定在哪里。这似乎与这个问题非常相似:http://stackoverflow.duapp.com/questions/34757352/how-do-i-create-a-linked-record-in-orientdb-using-pyorient-library
外面有什么自以为是的人吗?巨蟒之神?Lucky s0bs?=)
发布于 2016-10-12 12:37:04
我已经使用pyorient的开发分支和最新版本的OrientDB 2.2.11在Python3上试用了您的示例。如果我传递这些值而不转义它们,那么您的示例似乎对我有效,并且我得到了正确的值。
所以这个测试是有效的:
def test_test1(self):
new_Node = {'@Nodes': {'Content': '',
'Abs_Address': '/u/c/2/a1–2',
'Type': 'section',
'Heading': ' Transferred',
'Value': u'1\u20132'}
}
self.client.record_create(14, new_Node)
result = self.client.query('SELECT * FROM V where Abs_Address="/u/c/2/a1–2"')
assert result[0].Abs_Address == '/u/c/2/a1–2'我认为您可能会将Unicode值保存为转义值,这就是事情变得棘手的地方。
我不信任自己替换值,所以我通常使用以下代码来转义我发送给orientdb的Unicode值:
import json
def _escape(string):
return json.dumps(string)[1:-1]以下测试将失败,因为转义值与数据库中的转义值不匹配,因此不会返回任何记录:
def test_test2(self):
new_Node = {'@Nodes': {'Content': '',
'Abs_Address': _escape('/u/c/2/a1–2'),
'Type': 'section',
'Heading': ' Transferred',
'Value': u'1\u20132'}
}
self.client.record_create(14, new_Node)
result = self.client.query('SELECT * FROM V where Abs_Address="%s"' % _escape('/u/c/2/a1–2'))
assert result[0].Abs_Address.encode('UTF-8').decode('unicode_escape') == '/u/c/2/a1–2'为了解决这个问题,您必须对该值进行两次转义:
def test_test3(self):
new_Node = {'@Nodes': {'Content': '',
'Abs_Address': _escape('/u/c/2/a1–2'),
'Type': 'section',
'Heading': ' Transferred',
'Value': u'1\u20132'}
}
self.client.record_create(14, new_Node)
result = self.client.query('SELECT * FROM V where Abs_Address="%s"' % _escape(_escape('/u/c/2/a1–2')))
assert result[0].Abs_Address.encode('UTF-8').decode('unicode_escape') == '/u/c/2/a1–2'这个测试将会成功,因为您现在将请求DB中的转义值。
https://stackoverflow.com/questions/39761684
复制相似问题