2011-07-12 29 views
0

我正在使用Python 2.6.6和SQLAlchemy 0.6.6來處理我的數據庫中的一對多關係,並且我不確定如何防止SQLAlchemy在類似數據已經存在的情況下添加新的子記錄。如何防止兒童在SQLAlchemy一對多關係中重新創建?

數據庫代碼:

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) 

示例腳本:

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() 

我第一次運行該示例腳本,以下顯示在數據庫(如預期):

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) 

如果我再次運行示例腳本,則可以看到現有的元數據記錄的作者ID已經設置爲空,新記錄,已插入:

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

您可以明確檢查列表的內容,並且只添加新的AuthorMetadata對象(如果它們不存在),而不是刪除整個集合並用全新對象重新創建它。這至少會避免丟棄以前創建的記錄。

你的使用案例匹配attribute_mapped_collectionassociation_proxy相當好,所以你可能想與其中一個。

+0

+1給column/attribute_mapped_collection。 –

+0

謝謝jd和Mark!我使用了關於映射集合和關聯代理以及http://stackoverflow.com/questions/1400537/dictionary-of-tags-in-declarative-sqlalchemy的建議來提出我之後的確切內容。 – christopherwright

相關問題