2

mysqlテーブルのサブセットを「本番」レプリカから開発/テストシステムに定期的に「コピー」するために使用するスクリプトでSAを使用しています。ソーステーブルとを単純に反映するコードを記述しましたmeta.create_all(destination_engine)use_alter=TrueFKの性質上、CircularDependencyErrorsやその他の問題が発生しないように、テーブルを作成するときにテーブルのForeignKeysに適用する必要があることがわかりました。メタデータを調べるまで、FKの数や名前がわからないと想定する必要があります。

私はSAに不慣れで、通常はJavaプログラマーです(あなたが言うように:D)。use_alter属性を変更しようとしました。最初は繰り返し:

tablesd = smeta.tables.items()
for tname, t in tablesd:
    for c in t.columns:
       for fk in c.foreign_keys:
            fk.use_alter = True
smeta.create_all(to_engine)

編集:上記のようにuse_alterプロパティを設定した後、create_all()がCircularDependencyErrorをスローしないことに注意することが重要です。そのコードを削除すると、create_all()が機能しません。作成からFKを削除していないようです...

これは明らかに機能しませんでした。次に、SAドキュメントの「反映された列のオーバーライド」を読みました。サンプルは次のとおりです。

mytable = Table('mytable', meta,
Column('id', Integer, primary_key=True), # override reflected 'id' to have primary key
Column('mydata', Unicode(50)),    # override reflected 'mydata' to be Unicode,   autoload=True)

各テーブルを個別に反映use_alter=TrueしてからFK定義に追加することは機能すると思いますが、名前と値、またはFK/列の数を想定することはできません。私はこのようなことをするために使用することについてたくさん読みましたDeclarativeBase、しかし私はそれがどのように機能するか本当にわかりません...

テーブルの任意のリストを取得して反映し、それぞれの外部キーのuse_alterオプションをオーバーライドするにはどうすればよいですか?私はこれを間違った方法で考えていますか?

4

1 に答える 1

5

答えは問題の中にありました(想像してみてください...)。各ForeignKeyオブジェクトにはuse_alter設定できる値がありますが、設定Constraintsできる個別のプロパティもあります ( API ドキュメントでこれを見つけることができませんでした。PyDev のデバッガーで実行した後、前者が設定されていることに気付きましたが、すべてConstraintsそれらに関連付けられていたキーはまだFalse. 私はそれらをtrueに設定しました:

for fk in table.foreign_keys:
    fk.use_alter=True
    fk.constraint.use_alter=True

これは私が探していたSQLを生成するようで、テーブルはノーCircularDependencyErrorsで正しく作成されmetadata.sorted_tables、エラーなしで正常に動作するようでした. 私は実際に自分のコードをリファクタリングし、正しい方法で物事を行うことができました!

SQLAlchemy を使用して複雑な FK を反映する DB-->DB を実行しようとしている人には、この回答とTyler Lesmann の記事が最適です。

*更新: *このメソッドの使用はピア レビューに合格し、現在は製品コードとして使用されています。うまくいきそうです!

于 2012-09-06T21:01:58.233 に答える