0

SQLAlchemy を学習するための小さなプロジェクトを開発しており、Flask と Flask-SQLAlchemy を使用しています。このプロジェクトは、一連のテレビ番組とそのエピソードをモデル化することを目的としています。

SQLAlchemy での INSERT または UPDATE (または「アップサート」) に関しては、ベスト プラクティスに頭を悩ませようとしていますが、この障害を乗り越えることができません。Model インスタンスを作成するたびに、SQLAlchemy (または Flask-SQLAlchemy) がINSERTステートメントを作成するようです! それは奇妙で、私はそれが正しいとは思いませんが、何かを見逃したのでしょうか?

これはモデルの簡略化されたバージョンで、Episode3 つの列の値で構成される複合主キーを使用します。そのうちの 1 つはShowモデルの外部キーです。

class Episode(db.Model):
    title = db.Column(db.String(256))
    season = db.Column(db.Integer, primary_key=True)
    episode = db.Column(db.Integer, primary_key=True)

    # relationships
    show_id = db.Column(db.Integer, db.ForeignKey('show.id'), primary_key=True)
    show = db.relationship('Show', backref=db.backref('episodes', lazy='dynamic'))

INSERTステートメントを生成するように見えるコードは次のとおりです。

show = Show.query.filter_by(something=139).first()
ep = Episode(**{'title': 'foo',
                'show': show,
                'season': 39,
                'episode': 1})
db.session.commit()

これは永続オブジェクトを参照していることに関係していると推測していますが、確かにこれはINSERT?を生成するべきではありません。

どんな助けでも大歓迎です!

Windows システムで Python 2.7 を使用しています。Flask 0.10.1、Flask-SQLAlchemy 1.0、および SQLAlchemy 0.8.3 を使用しており、すべて pip 経由でインストールされています。

4

1 に答える 1

1

あなたが直面している問題は、いわゆるカスケードに関連しています。一言で言えば、次のように機能します: 作業しているオブジェクトの 1 つが既にセッションにある場合 (この場合Show、セッションを介してデータベースからクエリを実行したため)、これを他のオブジェクトにカスケードします。これに関連します。

そうしたくない場合は、この動作を無効にする方法があります。

    show = db.relationship('Show', backref=db.backref('episodes', lazy='dynamic'), cascade=None)

Noneドキュメントでこれを見つけることができないため、それが正しい値であると100%確信しているわけではありませんFalse。「デフォルトを使用」を示しているだけです。

補足として、なぜこのようにしているのか疑問に思っています。問題の説明で読んだことから、次のようにしたいと思います。

ep = Episode.query.filter(Episode.show_id == 139).filter(Episode.season == 39).filter(Episode.episode == 1).first()
if ep:
    # update
else:
    # create new
于 2013-10-28T22:20:25.003 に答える