2016-11-18 1 views
8

(MariaDBの上で実行されている)私のSQLAlchemyのアプリケーションは、後者が前者の子レコードである二つのモデルMyModelAMyModelB含まれていますDB例外後のSQLAlchemyロールバックの不具合?

class MyModelA(db.Model): 
    a_id = db.Column(db.Integer, nullable=False, primary_key=True) 
    my_field1 = db.Column(db.String(1024), nullable=True) 

class MyModelB(db.Model): 
    b_id = db.Column(db.Integer, nullable=False, primary_key=True) 
    a_id = db.Column(db.Integer, db.ForeignKey(MyModelA.a_id), nullable=False) 
    my_field2 = db.Column(db.String(1024), nullable=True) 

をこれらは私が作成MyModelAMyModelBのインスタンスである:

>>> my_a = MyModelA(my_field1="A1") 
>>> my_a.aid 
1 
>>> MyModelB(a_id=my_a.aid, my_field2="B1") 

I有しMyModelAのインスタンスa_id==1削除以下のコード:

0を

私は私が手に予期しない結果で、このコードを見て実行します。

#1) Number of MyModelAs: 1 
#2) Cannot delete instance of MyModelA because it has child record(s)! 
#3) Number of MyModelAs: 0 

は、削除はおそらく失敗し、DBは、ロールバックが発生する例外をスローします。しかし、ロールバックした後でさえ、テーブルの行数は、削除されていない行が実際には消えていることを示しています。

どうしてですか?これをどうすれば解決できますか? SQLAlchemyのバグのようです。

+0

自動コミットが無効になっているかどうかを確認しましたか? –

+0

同じ考え:あなたはMariaDBを使っていると言います。 MariaDBのエンジンは? MyISAMはトランザクションをサポートしないので、常に「自動コミット」モードになります –

+0

sqlalchemyによって生成されるクエリは何ですか? 'SELECTs'は' FOR UPDATE'を持っていますか? –

答えて

0

TL; DR この問題は、明示的な関係宣言の不足に関連している可能性があります。

たとえば、hereオブジェクトの関係のサンプルがあります。 ForeignKeyフィールドの使用に加えて、クラスは明示的にその接続を定義するためにrelationshipディレクティブを使用します。 session API documentationでは、次のテキストが表示されます。

オブジェクト参照がオブジェクト・レベルではなく、関係を管理するために、SQLAlchemyの方に暗示するかもしれない外部キーレベル

で構成されなければなりません。私は深く根本的なメカニズムに精通していませんが、これが起こる可能性があります。あなたのセッションにはMyModelAオブジェクトしか含まれていません。 MyModelBの定義でrelationship()ディレクティブを使用しなかったので、MyModelAタイプのオブジェクトは、他のオブジェクトがForeignKeyでそれらを参照する可能性があるという事実に気づいていません。したがって、セッションがコミットしようとしているとき、そのオブジェクトを削除すると他のオブジェクトに影響を与えることは認識されず、そのトランザクションメカニズムでは考慮されません。 関係を明示的に追加すると、その動作が妨げられる可能性があります。

関連する問題