0

更新: Ivan Mainetti の提案に基づいて、github で問題を開きました。そこに重きを置きたい場合は、https ://github.com/orientechnologies/orientdb/issues/6757 です。

私は OrienDB に基づいたデータベースに取り組んでおり、Python インターフェイスを使用しています。私はそれでかなり幸運でした.

データベースにアップロードするデータ構造は次のようになります。

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 要素に pyorient が何とか窒息している Unicode 文字があるためだと思います。

作成したいレコードの Abs_address は /u/c/2/a1–2 ですが、上記の my データ構造に値を渡すと得られるノードは次のとおりです。

{'@Nodes': {'Content': '', 'Abs_Address': u'/u/c/2/a1\u20132', 'Type': 'section', 'Heading': ' Transferred', 'Value': u'1\u20132'}}

どういうわけか私の問題は、pythonがユニコードとASCII文字列/文字を混在させていることだと思いますか? 私はPythonに少し慣れていないので、型を宣言していません. それとも、これはユニコードを好まない pyorient のインスタンスですか? 私はこれで髪を引き裂いています。どんな助けでも大歓迎です。

エラーが何らかのテキスト エンコーディングではなく 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

バックエンド データベースがアドレスに対して null オブジェクトを取得していることを示唆しているため、このエラーは奇妙です。どうやらこの「アドレス」のエントリを作成したようですが、それは私がやりたいことではありません。ユニコードを含むアドレス文字列がデータベースで null になる理由がわかりません... new_Node データ構造に入力した正確な文字列を使用して、orientDB スタジオで作成できます...しかし、python を使用して行うことはできません同じこと。

誰か助けて?

編集:

Laurent のおかげで、問題を unicode オブジェクトと pyorient に関係するものに絞り込むことができました。渡す変数が unicode 型の場合は常に、pyorient アダプターは null 値を OrientDB データベースに送信します。問題の原因となっている値は ndash 記号であると判断し、Laurent はこのコードを使用してそれをマイナス記号に置き換えるのを手伝ってくれました

.replace(u"\u2013",u"-")

ただし、それを行うと、pyorient は unicode オブジェクトを取得し、それを null 値として渡します...これは良くありません。str(...) を使用して文字列を再キャストすることで、この短期間を修正できます。これにより、差し迫った問題が解決するようです。

str(Ono.absolute_address.replace(u"\u2013",u"-"))

. 問題は、DB データに記号やその他の異常な文字が含まれることがわかっていることです。データベースがユニコード文字列をサポートしていることはわかっています。手動で追加したり、SQL 構文を使用して pyorient や Python では実行できないことを実行したりできるためです。 . これは、この問題と非常によく似ているようです: http://stackoverflow.duapp.com/questions/34757352/how-do-i-create-a-linked-record-in-orientdb-using-pyorient-library

そこにパイオリエントな人はいますか?パイソンの神?ラッキーs0bs?=)

4

1 に答える 1

1

OrientDB 2.2.11の最新バージョンを使用してpyorientの開発ブランチを使用して、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'

ユニコード値をエスケープ値として保存している可能性があると思いますが、それが難しいところです。

私は値を自分で置き換えることを信用していないので、通常、orientdb に送信する Unicode 値を次のコードでエスケープします。

import json
def _escape(string):
    return json.dumps(string)[1:-1]

次のテストは、エスケープされた値が DB のエスケープされた値と一致せず、レコードが返されないため失敗します。

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'

これを修正するには、値を 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 でエスケープされた値を要求するため、このテストは成功します。

于 2016-10-12T04:37:03.533 に答える