2017-08-01 5 views
0

sqlalchemyスコープのセッションで作業していて、既存の行を正しく更新できません。ここでSQLAlchemyの行を正しく更新できません

は私のモデルです:

db = scoped_session(sessionmaker()) 
Base = declarative_base() 

class Song(Base): 
    __tablename__ = 'song' 
    id = Column(Integer, primary_key=True) 
    artist_id = Column(Integer, ForeignKey('artist.id')) 
    artist_title = Column(Text) 
    title = Column(Text) 
    artist = relationship('Artist', backref='songs') 
    preview_url = Column(Text, default=None) 


class Artist(Base): 
    __tablename__ = 'artist' 
    id = Column(Integer, primary_key=True) 
    title = Column(Text) 

    similar_artists = relationship('Artist', 
            secondary=followers, 
            primaryjoin=(followers.c.follower_id == id), 
            secondaryjoin=(followers.c.followed_id == id), 
            backref=backref('followers', lazy='dynamic'), 
            lazy='dynamic') 

Index('my_index', Artist.id, unique=True, mysql_length=255) 

私はデシベルを埋めてきたし、歌の行は、デバッガともpgwebインタフェースのデータで埋めすべての列を持っていることがわかります。ビューでは、私は、曲のリストを取得するクエリを作成し、それらを次のように更新する:これは私がそれを行うとartist.idをコミットしたら、どれもなっていない、しかし、行にpreview_urlを追加

# song.artist_id has an integer value 
song.preview_url = preview_url # Just a string 
# db.query(Song).filter(Song.id == song.id).update({'preview_url':preview_url}) #Produces same result as above 

db.commit() 
# song.artist_id becomes None 

完全に異なるフィールドを更新していたにもかかわらず、ソングのインスタンスで。私はそれをデバッガとpgwebインタフェースで見ることができます。

UPDATE:私は、行への変更を行うと、それはまだNonesong.artist_idを置き換える前に、私はdb.commit()権利を試してみました。これは行の更新がそれと関係がないことを意味します。したがって、私はsongで行う前処理でなければなりません。行を更新してコミットする前に、セッション内のすべての変更を取り除く方法はありますか?

誰でもこの現象が発生しましたか?外部キーなので、artist.idを明示的に設定する必要がありますか?

+0

をいいえ、再びartist.idを指定する必要はありません。データが正常にデータベースに更新/コミットされましたか? – ionheart

+1

[mcve]を入力してください。いくつかの "前処理"について言及します。それも含めてください。 –

答えて

0

私はこの魚の行動を追跡することができました。この問題は実際に前処理で問題になりました。

まもなく私はリスト内の多くのアーティストのArtist.songsを集めていましたが、後で私はこのリストから飛び出していましたが、このリストは特別です。つまり、SQLAlchemyのInstrumented Collectionです。 :

「インストルメンテーションは、コレクションの通常の操作を追跡し、フラッシュ時にデータベースに書き込まれている変化をもたらしていることを意味し、」

私は実際にArtist削除されたこのコレクションから、ポップで - Songの関係を、したがって、外部キーはになっていました。

私のサンプルコードでは、そのような何かに見えた:

artists = db.query(Artist).all() 
all_songs = [] 
for artist in artists: 
    all_songs.append(artist.songs) 

all_songs.pop(0) # This would delete the Artist-Song relation after the commit 
関連する問題