6

本番環境でmysqlを実行していますが、メモリデータベースのsqliteで簡単なテストを実行したいと思います。

従来のmysqldbには、宣言型モデル(declarative_baseのサブクラス化)で宣言されたmysql固有のタイプの列を持つテーブルがあります。mysqlにアクセスせずにいくつかの簡単なテストを実行したいので、モデルの列を交換する必要があります。

どうすればよいですか?モデル内のテーブルを交換するためにパッチャー/アンパッチャーを作成しようとしましたが、いくつかのテストを実行すると、次のようになります。

OperationalError: (OperationalError) near ")": syntax error u'\nCREATE TABLE my_table (\n)\n\n' ()

これは、私が列に適切にパッチを当てていないことを私に思わせます。

誰かが私がこれを行う方法を知っていますか?私は何が間違っているのですか?

現在、新しい列を作成し、新しいTableオブジェクトをアタッチし__table__て、古いテーブルを保存しています。

DBが作成され、create_all()が作成され、convert_columnsがsetUpで実行されます。drop_all()とrevert_columnsは、私のテストのtearDown中に実行されます

mysql_sqlite_mapping = {INTEGER: Integer,
                        MEDIUMINT: Integer,
                        TEXT: text}    

def convert_columns(self, my_class, mapping):
    for column in my_class.__table__.columns:
        if type(column.type) in mapping:
            replacement_col = Column(column.name,
                                     mapping[type(column.type)],
                                     primary_key=column.primary_key,
                                     nullable=column.nullable,
                                     key=column.key,
                                     unique=column.unique)

            converted_columns.append(replacement_col)

    self.registry[my_class] = my_class.__table__

    my_class.__table__.metadata.remove(my_class.__table__)
    my_class.__table__ = Table(my_class.__table__.name,
                               my_class.__table__.metadata)

    for column in converted_columns:
        my_class.__table__.append_column(column)

    return my_class

def revert_columns(self, my_class):
    saved_table = self.registry[my_class]

    metadata = my_class.__table__.metadata
    my_class.__table__.metadata.remove(my_class.__table__)

    model_class.__table__ = Table(saved_table.name,
                                  metadata)

    for column in saved_table.columns:
        column.table = None
        my_class.__table__.append_column(column)

    self.registry.pop(my_class)
4

1 に答える 1

8

以下が、この種の変更に対処するためのより良い方法に役立つことを願っています。しかし、句に列がないため、エラーは奇妙ですCREATE TABLE。そのため、これがあなたの質問に対する直接的な回答/解決策ではないと思います。

とにかく、テーブルと列を完全に置き換える代わりに、カスタム SQL コンストラクトとコンパイル拡張機能 / ダイアレクト固有のコンパイル ルールを使用してみませんか。テーブル定義を変更せずに sqlite の適切な SQL ステートメントを生成するサンプル コードを参照してください。

from sqlalchemy.ext.compiler import compiles
from sqlalchemy.dialects.mysql import MEDIUMINT, INTEGER, TEXT

@compiles(MEDIUMINT, 'sqlite')
def compile_MEDIUMINT(element, compiler, **kw):
    """ Handles mysql MEDIUMINT datatype as Integer in sqlite.  """
    return compiler.visit_integer(element, **kw)

@compiles(INTEGER, 'sqlite')
def compile_INTEGER(element, compiler, **kw):
    """ Handles mysql INTEGER datatype as Integer in sqlite.  """
    return compiler.visit_integer(element, **kw)


@compiles(TEXT, 'sqlite')
def compile_TEXT(element, compiler, **kw):
    """ Handles mysql TEXT datatype as text in sqlite.  """
    return compiler.visit_text(element, **kw)
于 2012-05-14T10:13:30.957 に答える