2011-11-28 214 views
3

嗨我有一個簡單的問題 - 我有2個表(地址和用戶 - 用戶有一個地址,很多用戶可以住在同一地址)...我創建了一個像這樣的sqlalchemy映射: 我讓我的會話,並嘗試查詢類似sqlalchemy關係映射

class Person(object): 
''' 
classdocs 
''' 
idPerson = Column("idPerson", Integer, primary_key = True) 
name = Column("name", String) 
surname = Column("surname", String) 
idAddress = Column("idAddress", Integer, ForeignKey("pAddress.idAddress")) 
idState = Column("idState", Integer, ForeignKey("pState.idState")) 
Address = relationship(Address, primaryjoin=idAddress==Address.idAddress) 

class Address(object): 
''' 
Class to represent table address object 
''' 
idAddress = Column("idAddress", Integer, primary_key=True) 
street = Column("street", String) 
number = Column("number", Integer) 
postcode = Column("postcode", Integer) 
country = Column("country", String) 
residents = relationship("Person",order_by="desc(Person.surname, Person.name)", primaryjoin="idAddress=Person.idPerson") 




    self.tablePerson = sqlalchemy.Table("pPerson", self.metadata, autoload=True) 
    sqlalchemy.orm.mapper(Person, self.tablePerson) 
    self.tableAddress = sqlalchemy.Table("pAddress", self.metadata, autoload=True) 
    sqlalchemy.orm.mapper(Address, self.tableAddress) 


myaddress = session.query(Address).get(1); 
print myaddress.residents[1].name 

=>我得到類型錯誤:「RelationshipProperty」對象不支持索引

我明白居民是有定義的關係,但赫克哪能得到給定地址分配給的居民的名單?! 感謝

回答

0

你可以嘗試地址後確定的人,有backref到地址 - 這將創建數組元素:如果你

myaddress = session.query(Address).get(1); 
for residents in myaddress.residents: 
    print name 

此外,:

class Address(object): 
__tablename__ = 'address_table' 
idAddress = Column("idAddress", Integer, primary_key=True) 

class Person(object): 
idPerson = Column("idPerson", Integer, primary_key = True) 
... 
address_id = Column(Integer, ForeignKey('address_table.idAddress')) 
address = relationship(Address, backref='residents') 

然後你就可以查詢在一個地址有很多居民可以使用加入進一步過濾:

resultset = session.query(Address).join(Address.residents).filter(Person.name=='Joe') 
# or 
resultset = session.query(Person).filter(Person.name=='Joe').join(Person.address).filter(Address.state='NY') 
and resultset.first() or resultset[0] or resultset.get(...) etc... 
+0

以及我有兩個類在單獨的文件。我有我的數據庫初始化對象,它做的ORM self.tableAddress = sqlalchemy.Table(「pAddress」,self.metadata,autoload = True) addressMapper = sqlalchemy.orm.mapper(Address,self.tableAddress) self.tablePerson = sqlalchemy.Table(「pPerson」,self.metadata,autoload = True) personMapper = sqlalchemy.orm.mapper(Person,self.tablePerson) 當我做了你的建議並得到AttributeError:'Address'對象沒有屬性「居民」。是不是問題autoload = True「聲明?我不認爲backref被創建 – kosta5

+0

我從來沒有用過.Table()...我的理解是,這是如果你連接到ORM外部的表。(正如在你的類中使用Table()或關係,但不能同時使用......)你可能會檢查 - http://www.sqlalchemy.org/docs/core/schema.html#binding-metadata-to-an-引擎或連接 –

+0

此外,使用關係()爲一個單獨的文件中定義的表類是可以的...只要確保您的導入不是循環的,否則在第一次創建表時會引發問題。 –

2

您在錯誤的地方定義了一段關係。我認爲你是混合Declarative Extensionnon-declarative使用:

  1. 使用declarative時,你在你的model定義你的關係。
  2. 否則,你映射model當確定他們table

如果選擇-2是你在做什麼,那麼你就需要從models刪除這兩個relationship定義,並將其添加到一個映射器(僅一個是足夠多的):

  1. Relatio:

    mapper(Address, tableAddress, 
    properties={'residents': relationship(Person, order_by=(desc(Person.name), desc(Person.surname)), backref="Address"),} 
    ) 
    

    很少關於上面的代碼更多的東西n僅在一側定義。 backref照顧對方。

  2. 你並不需要指定primaryjoin(只要你有指定一個ForeignKey和SA能夠推斷出列)
  3. order_by配置不正確,見上面代碼其中工程版本。