1

私は sqlite のマニフェスト タイピング / タイプ アフィニティのアイデアが好きです。

http://www.sqlite.org/datatype3.html

基本的に、列のアフィニティを「数値」に設定すると、整数型または浮動小数点型をダックしてそれらを格納しますが、必要に応じて文字列を格納することもできます。これは、列に格納したいデータが事前にわからない場合に、列に最適な「デフォルト」タイプのようです。

だから私は行きます:

metadata = MetaData()
new_table = Table(table_name, metadata )
for col_name in column_headings:
    new_table.append_column(Column(col_name, 
                                   sqlite.NUMERIC, #this should duck-type numbers but can handle strings as well
                                   primary_key=col_name in primary_key_columns))
new_table.create(self.engine, checkfirst=False)

しかし、テーブルに「abc」などの文字列値を保存しようとすると、sqlalchemy が失敗します。

  File "[...]\sqlalchemy\processors.py", line 79, in to_float
    return float(value)
ValueError: invalid literal for float(): abc

ブー、ヒス。それで、sqliteに型付けをさせるようにsqlalchemyを納得させる方法はありますか? おそらく、sqlachemy.dialects.sqlite の代わりに sqlalchemy.types の型を使用できますか?

[編集:] ボーナス ポイント: イントロスペクション/リフレクションを介してテーブルにアクセスできる必要があります。したがって、これを meta.reflect() で機能させる何らかの方法は素晴らしいでしょう! ;-)

4

2 に答える 2

1

OK、これが私が思いついたものです:

http://www.sqlalchemy.org/docs/reference/sqlalchemy/types.html#custom-typesに従って、カスタム列タイプを定義し ます

ドキュメントといくつかの試行錯誤の組み合わせにより、これが得られました。

class MyDuckType(sqlalchemy.types.TypeDecorator):
    """
    SQLALchemy custom column type, designed to let sqlite handle the typing 
    using 'numeric affinity' which intelligently handles both numbers and strings
    """
    impl = sqlite.NUMERIC

    def bind_processor(self, dialect):
        #function for type coercion during db write
        return None #ie pass value as-is, let sqlite do the typing

    def result_processor(self, dialect, coltype):
        #function for type coercion during db read
        return None #ie pass value as sqlite has stored it, should be ducktyped already

    def process_bind_param(self, value, dialect):
        #any changes to an individual value before store in DN
        return value

    def process_result_value(self, value, dialect):
        #any changes to an individual value after retrieve from DB
        return value

    def copy(self):
        #not quite sure what this is for
        return MyDuckType()

現在の sqlalchemy 方言タイプは bind_processor で to_float を返します。これが、以前にエラーが発生した理由です。imvvho、これはバグです。

私のボーナスポイントについて:metadata.reflect()コードで列タイプを手動でMyDuckTypeに設定します:

def get_database_tables(engine):
    meta = MetaData()
    meta.reflect(bind=engine)
    tables = meta.raw_tables
    for tbl in tables.values():
        for col in tbl.c:
            col.type = MyDuckType()
    return tables

私にはうまくいくようです。提案/改善点はありますか?

于 2010-06-15T15:21:50.083 に答える
0

基本的に、列のアフィニティを「数値」に設定すると、整数型または浮動小数点型をダックしてそれらを格納しますが、必要に応じて文字列を格納することもできます。

列の型をまったく宣言しない場合、SQLite では変換を実行せずに任意の型を格納できます。123と区別したい場合は、これを選択することをお勧めします'123'

于 2010-07-03T00:54:38.693 に答える