3

そのため、複数の大きなxmlファイルをループし、MySQLの挿入ステートメントを生成して賃貸物件のリストをデータベースに追加しています。問題は、多くの要素にÅやçなどの特殊文字、さらにはダッシュや箇条書きが含まれていることです。

要素をうまく取得でき、挿入ステートメントを保持する文字列を作成できますが、ステートメントを実行しようとするとすぐに次のファイルにダンプされます。

独自のtryブロックに挿入があり、xmlドキュメントの残りの部分を破棄するのではなく、次のリストに進むことができると考えていますが、それは起こりません。

インサートがutf-8でエンコードされていることを確認しようとしましたが、違いはありません。

これが私が持っているコードの要点です:

try:
    print "About to read file: "+fullpath
    data = f.read()  #read the file into a string
    print "Data read from file, now closing: "+fullpath
    f.close()  #close the file, we don't need it any more
    dom = minidom.parseString(data)  #parse the xml
    #get the first child node -- <property_data>
    property_data = dom.firstChild
    properties = property_data.getElementsByTagName('property')
    for property in properties:
        try:
            print "getting details"
            details = property.getElementsByTagName('property_details')
            for detail in details:
                print "attempting to get detail values"
                try:
                     checkin = getElementValue('check_in', detail)
                     name = stripCDATA(getElementValue('name', detail))
                     checkout = getElementValue('check_out', detail)

                                ...etc, etc...

                      print "building insert string"
                      sql = u"""insert into PROPERTY(NAME, CHECKIN, CHECKOUT, etc...)
                                  values(%s,%s,%s,...)""".encode('utf-8')
                      print "starting insert with query:"
                      print sql % (name,checkin,checkout, etc...)
                      try: #HERE IS WHERE THE PROBLEM HAPPENS
                          cursor.execute(sql,(name, checkin, checkout, ...))
                          #display number of rows affected
                          print "Number of rows inserted: %d" % cursor.rowcount
                          conn.commit()
                      except Exception as (errno, strerror):
                          print "Problem inserting the property. Error({0}): {1}".format(errno, strerror)
                except Exception as (errno, strerror):
                    print "Problem with reading/inserting details. Error({0}): {1}".format(errno, strerror)
        except Exception as (errno, strerror):
            print "The loop broke with the following error({0}): {1}".format(errno, strerror)
            errCount += 1
            print "This has happened %d times" % (errCount)
except: #HERE IS WHERE I GET DUMPED TO
    print "Something bad happened while reading and inserting"

ご覧のとおり、さまざまな箇所に線が印刷されているので、いつ爆発するかを確認できます。

ファイルが正しく解析されていること、すべての要素が正しく取得されていること、挿入ステートメントが正しく作成されていること、取得した要素のいずれにも特殊文字が含まれていないプロパティをヒットしている限り、データベースに正しく挿入します。特殊文字に当たるとすぐに壊れ、壊れると3レベル高くなります。今のところ、怒鳴ったり髪を抜いたりしても効果がありません。

何か案は?

@deadlyからの提案に従って、ブロックを除くすべての試行を削除し、次のトレースバックを取得しました。

トレースバック(最後の最後の呼び出し):

cursor.execute(sql、([bunch of var names]))のファイル "dbinsert2.py"、行118

ファイル"/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py"、159行目、execute query = query%db.literal(args)

ファイル"/usr/lib/python2.7/dist-packages/MySQLdb/connections.py"、行264、リテラルreturn self.escape(o、self.encoders)

ファイル"/usr/lib/python2.7/dist-packages/MySQLdb/connections.py"、行202、unicode_literal return db.literal(u.encode(unicode_literal.charset))

UnicodeEncodeError:'latin-1'コーデックは位置20の文字u'\ u2013'をエンコードできません:序数が範囲内にありません(256)

4

1 に答える 1

2

そのコードすべてを処理する忍耐力を持つ人は多くありません。

すべての試行を取り除くことから始めます...例外。Python は、それがなくても喜んで例外を発生させます。

try... を使用する必要があるのは、バグ検出以外の例外で特別な処理を行う場合を除きます。この段階では、print ステートメントの方が良い友達です。また、try...excepts を省略した場合 (少なくとも使用している方法では)、Python はトレースバックも出力します。これは、コードと共に投稿する必要があります。

コードを整理したら、このトレースバックを投稿してください。

編集: トレースバックをありがとう。これで、使用しているエンコーディング (utf-8) と MySQLdb Python ライブラリが使用するデフォルトのエンコーディング (latin-1) の間に不一致があることがわかります。charset='utf8'にパラメータとして渡す必要がありますconnect()。(これは MySQL が文字セットのリストを保存する方法であるため、'utf8' にダッシュはありません。)

于 2012-06-07T22:07:49.097 に答える