2011-11-28 215 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配置不正确,见上面代码其中工程版本。