2012-03-06 8 views
2

SQLAlchemyを使用してソースデータベース(ここではMSSQL)をターゲットデータベース(ここではメモリ内のSQLite)にコピーする少しのコードがあります。このコピーの一環として、我々はターゲットにソースからテーブル情報をコピーします。テーブルの作成中にDEFAULT句を変更します

for table in source: 
    table.tometadata(metadata_target) 
    # some more stuff (hack: could alter table here) 
metadata_target.create_all() 

テーブルをコピーする場合、DEFAULT条項がそのままコピーされます。例えば。 SQLiteの中にコピーされた列には、次のようになります。GETUTCDATE()はSQLiteの関数ではないので

CREATE TABLE "TableName" (
    -- ... 
    "TimeStamp" DATETIME DEFAULT (GETUTCDATE()) NOT NULL, 
    -- ... 
) 

これは動作しません。

私は、例えばDATE('now')またはドロップでGETUTCDATE()を置き換える(I変更または値と方言(複数可)に応じて、DEFAULT部分の発生を抑制することができるいずれかのSQLAlchemyのDDLコンパイラ(私は推測)にフックを探していますNEWID()の完全なデフォルト句)。

私はthis part of the documentation(クロスコンパイル時に特定のタイプを処理するために使用します)を見ましたが、DEFAULTの句を処理する方法はわかりません。私はそれが正しいツールであるかどうかも分かりません。私はこれを(SQLAlchemyの「作成」の後にテーブルを変更することで)ハックすることができますが、もっと汎用的なソリューションを好むでしょう。

答えて

1

また、SQLite接続用にGETUTCDATE関数を実装することもできます。

+0

+1私はこれをいくつかのケースではすでに行っていますが、 'GETUTCDATE'はSQLiteで多かれ少なかれ同等の機能を持っていますので、私はカスタム関数を使いたくありません。私は現在、これを "手動で"置き換えていますが、これはハックです。 – stephan

1

もう1つ解決策がありますが、それを台無しにしてデータベースが使用できなくなります。それは動作しますが、推奨されません。 SQLiteは、sqlite_masterという名前のテーブルにスキーマを保持します。通常このテーブルに書き込むことはできませんが、pragma writable_schema=onを使用すると書き込むことができます。何か変更を加えてプラグマをオフにします。最後に、SQLiteの下でスキーマが変更されたために問題が発生しないように、データベースを閉じてから再度開きます。

+0

これが私がハックと呼ぶものです。 Worth a +1;)私の現在の解決策は、基本的に 'table.tometadata(metadata_target)'と 'metadata_target.create_all()'の呼び出しの間でスキーマを変更します。これが私が思いつく最高の解決策です。私は、SQLAlchemyがコンパイラへのフックでDDLを直接変更できるようにしたいと思っていましたが(他のケースでは '@ compiles'デコレータと同じように)、これはそうではないようですので、私はこのハック – stephan

関連する問題