9

Unicode からの変換で問題が発生していることはわかっていますが、どこで発生しているのかわかりません。

HTML ファイルのディレクトリから最近のエルオペアン旅行に関するデータを抽出しています。一部のロケーション名には非 ASCII 文字 (é、ô、ü など) が含まれています。正規表現を使用して、ファイルの文字列表現からデータを取得しています。

見つけた場所を印刷すると、文字が印刷されるため、エンコードは問題ないはずです。

Le Pré-Saint-Gervais, France
Hôtel-de-Ville, France

SQLAlchemy を使用して SQLite テーブルにデータを保存しています。

Base = declarative_base()
class Point(Base):
    __tablename__ = 'points'

    id = Column(Integer, primary_key=True)
    pdate = Column(Date)
    ptime = Column(Time)
    location = Column(Unicode(32))
    weather = Column(String(16))
    high = Column(Float)
    low = Column(Float)
    lat = Column(String(16))
    lon = Column(String(16))
    image = Column(String(64))
    caption = Column(String(64))

    def __init__(self, filename, pdate, ptime, location, weather, high, low, lat, lon, image, caption):
        self.filename = filename
        self.pdate = pdate
        self.ptime = ptime
        self.location = location
        self.weather = weather
        self.high = high
        self.low = low
        self.lat = lat
        self.lon = lon
        self.image = image
        self.caption = caption

    def __repr__(self):
        return "<Point('%s','%s','%s')>" % (self.filename, self.pdate, self.ptime)

engine = create_engine('sqlite:///:memory:', echo=False)
Base.metadata.create_all(engine)
Session = sessionmaker(bind = engine)
session = Session()

ファイルをループして、各ファイルのデータをデータベースに挿入します。

for filename in filelist:

    # open the file and extract the information using regex such as:
    location_re = re.compile("<h2>(.*)</h2>",re.M)
    # extract other data

    newpoint = Point(filename, pdate, ptime, location, weather, high, low, lat, lon, image, caption)
    session.add(newpoint)
    session.commit()

各挿入で次の警告が表示されます。

/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/engine/default.py:230: SAWarning: Unicode type received non-unicode bind param value 'Spitalfields, United Kingdom'
  param.append(processors[key](compiled_params[key]))

そして、次のようなテーブルで何かをしようとすると:

session.query(Point).all()

私は得る:

Traceback (most recent call last):
  File "./extract_trips.py", line 131, in <module>
    session.query(Point).all()
  File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/orm/query.py", line 1193, in all
    return list(self)
  File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/orm/query.py", line 1341, in instances
    fetch = cursor.fetchall()
  File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/engine/base.py", line 1642, in fetchall
    self.connection._handle_dbapi_exception(e, None, None, self.cursor, self.context)
  File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.5.4p2-py2.5.egg/sqlalchemy/engine/base.py", line 931, in _handle_dbapi_exception
    raise exc.DBAPIError.instance(statement, parameters, e, connection_invalidated=is_disconnect)
sqlalchemy.exc.OperationalError: (OperationalError) Could not decode to UTF-8 column 'points_location' with text 'Le Pré-Saint-Gervais, France' None None

元の文字をそのままにして、場所の名前を正しく保存して返すことができるようにしたいと考えています。どんな助けでも大歓迎です。

4

3 に答える 3

7

sqlalchemy.orgから

セクション 0.4.2 を参照

String と create_engine() に新しいフラグを追加し、_unicode=(True|False|'warn'|None) をアサートします。デフォルトは Unicode タイプのcreate _engine() および StringFalseです。の場合 、Unicode 以外のバイト文字列がバインド パラメータとして渡されると、すべての Unicode 変換操作で例外が発生します。'warn' は警告になります。すべての Unicode 対応アプリケーションで Python Unicode オブジェクト (つまり、「hello」ではなく「u'hello」) を適切に使用して、データのラウンドトリップが正確に行われるようにすることを強くお勧めします。None'warn'True

Unicode 以外のバイト文字列を入力しようとしていると思います。おそらく、これはあなたを正しい軌道に導くかもしれませんか?何らかの形式の変換が必要です。'hello' と u'hello' を比較してください。

乾杯

于 2009-06-08T21:34:59.147 に答える
7

Unicode 列に String ではなく Unicode の列タイプを使用してみてください。

Base = declarative_base()
class Point(Base):
    __tablename__ = 'points'

    id = Column(Integer, primary_key=True)
    pdate = Column(Date)
    ptime = Column(Time)
    location = Column(Unicode(32))
    weather = Column(String(16))
    high = Column(Float)
    low = Column(Float)
    lat = Column(String(16))
    lon = Column(String(16))
    image = Column(String(64))
    caption = Column(String(64))

編集:コメントへの応答:

Unicode エンコーディングに関する警告が表示される場合は、次の 2 つの方法を試すことができます。

  1. 現在地をユニコードに変換します。これは、ポイントを次のように作成することを意味します。

    newpoint = Point(ファイル名, pdate, ptime, unicode(location), weather, high, low, lat, lon, image, caption)

    Unicode 変換では、文字列または Unicode 文字列が渡されると Unicode 文字列が生成されるため、何を渡すかを気にする必要はありません。

  2. それでもエンコーディングの問題が解決しない場合は、unicode オブジェクトで encode を呼び出してみてください。これは、次のようなコードを使用することを意味します。

    newpoint = Point(filename, pdate, ptime, unicode(location).encode('utf-8'), weather, high, low, lat, lon, image, caption)

    この手順はおそらく必要ありませんが、本質的には、Unicode オブジェクトを Unicode コードポイントから特定のバイト表現 (この場合は utf-8) に変換することです。Unicode オブジェクトを渡すときに SQLAlchemy がこれを行うことを期待していますが、そうでない場合もあります。

于 2009-06-08T19:08:56.663 に答える