更新:我根据Ivan Mainetti的建议在github上打开了一个问题。如果你想在那里称重,那就是:https://github.com/orientechnologies/orientdb/issues/6757
我正在开发一个基于OrienDB的数据库并使用python接口。我已经运气好了,但在处理某些unicode角色时,我遇到了一个似乎是驱动程序(pyorient)的问题。
我上传到数据库的数据结构如下所示:
new_Node = {'@Nodes':
{
"Abs_Address":Ono.absolute_address,
'Content':Ono.content,
'Heading':Ono.heading,
'Type':Ono.type,
'Value':Ono.value
}
}
我在OrientDB / 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的地址字符串在数据库中出现空...我可以通过orientDB studio使用我输入new_Node数据结构的确切字符串来创建...但我不能使用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
那里有人吗?蟒蛇神?幸运的s0bs? =)
答案 0 :(得分:1)
我在python上使用最新版本的OrientDB 2.2.11尝试了Python 3上的示例。如果我在不转义值的情况下传递值,那么您的示例似乎对我有用,并且我得到了正确的值。
所以这个测试有效:
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中的转义值。