私はPython 2.6.6とSQLAlchemy 0.6.6を使用してデータベース内の1対多の関係を処理していますが、類似したデータがすでに存在する場合にSQLAlchemyが新しい子レコードを追加するのを防ぐ方法は不明です。子どもがSQLAlchemyの1対多リレーションシップで再作成されないようにするにはどうすればよいですか?
データベースコード:
from sqlalchemy import *
from sqlalchemy.orm import backref, relationship, sessionmaker, create_session
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
# Parent table, no foreign key.
class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True)
username = Column(String)
author_metadata = relationship('AuthorMetadata', backref='author')
# Child table, many records with same author_id.
class AuthorMetadata(Base):
__tablename__ = 'author_metadata'
id = Column(Integer, primary_key=True)
author_id = Column(Integer, ForeignKey('authors.id'))
metakey = Column(String)
metavalue = Column(Text)
スクリプト例:
dev=# select id from authors where username = 'Godfrey';
id
------
5025
(1 row)
dev=# select id, author_id, metakey, metavalue from author_metadata order by id desc limit 2;
id | author_id | metakey | metavalue
-------+-----------+----------+-----------
85090 | 5025 | posts | 5
85089 | 5025 | location | New York
(2 rows)
:
if __name__ == '__main__':
engine = create_engine('database_details', pool_recycle=90)
session = create_session(bind=engine)
author = session.query(Author).filter_by(username='Godfrey').first()
if not author:
author = Author()
author.username = 'Godfrey'
author.author_metadata = [
AuthorMetadata(metakey='location', metavalue='New York'),
AuthorMetadata(metakey='posts', metavalue='5')]
session.add(author)
session.flush()
私は例のスクリプトを実行する最初の時間は、以下のデータベース(予想通り)に表示されます。
サンプルスクリプトをもう一度実行すると、既存のメタデータレコードの作成者IDがnullに設定して、新しいレコードが挿入されています:
dev=# select id, author_id, metakey, metavalue from author_metadata order by id desc limit 4;
id | author_id | metakey | metavalue
-------+-----------+----------+-----------
85092 | 5025 | posts | 5
85091 | 5025 | location | New York
85090 | | posts | 5
85089 | | location | New York
(4 rows)
私は、これは驚くべき見つけることはありませんが、それが唯一の削除/修正/挿入する必要があることをSQLAlchemyのに通信できるようにする良い方法がある場合は疑問に思って新しいメタデータのリストが既存のリストと異なる場合は、作成者のメタデータ行。
+1 to column/attribute_mapped_collection。 –
jdとマークをありがとう!マップされたコレクションとアソシエーションのプロキシーに関する提案をhttp://stackoverflow.com/questions/1400537/dictionary-of-tags-in-declarative-sqlalchemyとともに使用して、私が後にしたことを思いついた。 – christopherwright