首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Pyorient中引发问题的常规Python Unicode / ASCII强制转换问题

在Pyorient中引发问题的常规Python Unicode / ASCII强制转换问题
EN

Stack Overflow用户
提问于 2016-09-29 12:54:06
回答 1查看 220关注 0票数 0

更新:根据Ivan Mainetti的建议,我在github上发布了一个问题。如果你想权衡一下,那就是:https://github.com/orientechnologies/orientdb/issues/6757

我正在开发一个基于OrienDB的数据库,并使用python接口。我有相当好的运气,但我遇到了一个问题,似乎是司机的(pyorient)书呆子在处理某些unicode字符。

我上传到数据库的数据结构如下所示:

代码语言:javascript
复制
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,但是当我将该值传递给上面的数据结构时,我得到的节点如下:

代码语言:javascript
复制
{'@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的相关信息。我使用以下代码创建记录:

代码语言:javascript
复制
rec_position = self.pyo_client.record_create(14, new_Node)

这就是我得到的错误:

代码语言:javascript
复制
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使用以下代码帮助我将其替换为减号

代码语言:javascript
复制
.replace(u"\u2013",u"-")

然而,当我这样做时,pyorient获取unicode对象,然后将其作为空值传递……这真是不太好。我可以通过使用str(...)重新转换字符串来解决这个问题这似乎解决了我眼前的问题:

代码语言:javascript
复制
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?=)

EN

回答 1

Stack Overflow用户

发布于 2016-10-12 12:37:04

我已经使用pyorient的开发分支和最新版本的OrientDB 2.2.11在Python3上试用了您的示例。如果我传递这些值而不转义它们,那么您的示例似乎对我有效,并且我得到了正确的值。

所以这个测试是有效的:

代码语言:javascript
复制
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值:

代码语言:javascript
复制
import json
def _escape(string):
    return json.dumps(string)[1:-1]

以下测试将失败,因为转义值与数据库中的转义值不匹配,因此不会返回任何记录:

代码语言:javascript
复制
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'

为了解决这个问题,您必须对该值进行两次转义:

代码语言:javascript
复制
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中的转义值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39761684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档