2016-02-13 44 views
1

我創建了一個Person(作爲作者)和Reference(作爲科學出版物)之間的許多一對多的關係。如何在使用relationship()和secondary-parameter(多對多)時使用SQLAlchemy中的order_by?

ReferenceAuthor = sa.Table('ReferenceAuthor', _Base.metadata, 
     sa.Column('ReferenceID', sa.Integer, sa.ForeignKey('Reference.ID'), primary_key=True), 
     sa.Column('PersonID', sa.Integer, sa.ForeignKey('Person.ID'), primary_key=True), 
     sa.Column('Index', sa.Integer) 
     ) 


class Reference(_Base): 
    __tablename__ = 'Reference' 

    _id = sa.Column('ID', sa.Integer, primary_key=True) 

    _authors = sao.relationship('Person', secondary=ReferenceAuthor) 


class Person(_Base): 
    __tablename__ = 'Person' 

    _id = sa.Column('ID', sa.Integer, primary_key=True) 

我想有通過ReferenceAuthor.Index下令Reference().authors的對象。

這裏的三個表來自一個國外的sqlite3數據庫。我無法改變表格的結構。我必須像他們一樣對付他們。

我可以找到relationship()的一些例子,但沒有任何結合使用secondary=

我試過了association_proxy並閱讀了相關文檔。

class ReferenceAuthor(_Base): 
    __tablename__ = 'ReferenceAuthor' 

    _reference_id = sa.Column('ReferenceID', sa.Integer, sa.ForeignKey('Reference.ID'), primary_key=True) 
    _person_id = sa.Column('PersonID', sa.Integer, sa.ForeignKey('Person.ID'), primary_key=True) 
    _index = sa.Column('Index', sa.Integer) 

    _person = sao.relationship('Person') 

class Reference(_Base): 
    __tablename__ = 'Reference' 

    _id = sa.Column('ID', sa.Integer, primary_key=True) 

    _authors = saa.association_proxy('ReferenceAuthor', 'Person') 

當我閱讀文檔時,我想我理解它背後的概念。但用我的代碼它不起作用,我不明白爲什麼。錯誤是

sqlalchemy.exc.InvalidRequestError: Mapper 'Mapper|Reference|Reference' has no property 'ReferenceAuthor'

+1

您需要使用[關聯代理](http://stackoverflow.com/questions/7417906/sqlalchemy-manytomany-secondary-table-with-additional-fields)。 – univerio

+0

@univerio謝謝你的提示。我閱讀了文檔並喜歡它。但是不能用我自己的代碼運行它。我使用'association_proxy'的一個使用示例更新了問題。 – buhtz

+1

請嚴格按照示例進行操作。要在引用'Person'的'Reference'上設置關聯代理,您需要首先在'Reference'列指定的'Reference'上建立一個關於'ReferenceAuthor'的關係。然後,添加一個關聯代理,其中包含您剛剛設置的關係的名稱和遠程類中的屬性名稱。如果您與'ReferenceAuthor'的關係被命名爲'_reference_authors',則需要編寫'association_proxy(「_ reference_authors」,「_person」)'。 – univerio

回答

0

解決方案1:

根據@univerio的漂亮評論回答:

class ReferenceAuthor(_Base): 
    __tablename__ = 'ReferenceAuthor' 

    _reference_id = sa.Column('ReferenceID', sa.Integer, sa.ForeignKey('Reference.ID'), primary_key=True) 
    _person_id = sa.Column('PersonID', sa.Integer, sa.ForeignKey('Person.ID'), primary_key=True) 
    _index = sa.Column('Index', sa.Integer) 

    _person = sao.relationship('Person') 


class Reference(_Base): 
    __tablename__ = 'Reference' 

    _id = sa.Column('ID', sa.Integer, primary_key=True) 

    _reference_authors = sao.relationship('ReferenceAuthor', 
              order_by=ReferenceAuthor._index) 
    _authors = saa.association_proxy('_reference_authors', '_person') 

解決方案2:

得到了來自sqla,郵件列表這個提示。根據我最初的問題中的第一個代碼:

_authors = sao.relationship('Person', 
          secondary=ReferenceAuthor, 
          order_by=ReferenceAuthor.c.Index) 

這看起來很簡單。

旁邊的問題:這兩種解決方案有什麼區別?

相關問題