реляционное отображение sqlalchemy - PullRequest
4 голосов
/ 28 ноября 2011

Привет, у меня простой вопрос - у меня есть 2 таблицы (адреса и пользователи - у пользователя один адрес, многие пользователи могут жить по одному и тому же адресу) ... Я создал отображение 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

=> Я получаю объект TypeError: RelationshipProperty не поддерживает индексирование

Я понимаю, что жители есть, чтобы определить отношения, но как, черт возьми, я могуполучить список жителей, которым присвоен данный адрес ?!Спасибо

Ответы [ 2 ]

3 голосов
/ 28 ноября 2011

Вы определяете отношения не в том месте. Я думаю, что вы смешиваете Декларативное расширение с non-declarative использование:

  1. при использовании declarative ваши отношения определяются в вашем model.
  2. в противном случае вы определяете их при отображении model в table

Если вы используете вариант-2, вам нужно удалить оба определения relationship из models и добавить его в маппер (достаточно только одного):

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

Еще немного о коде выше:

  1. Отношение определяется только с одной стороны. backref заботится о другой стороне.
  2. Вам не нужно указывать primaryjoin (если вы указали ForeignKey и SA может выводить столбцы)
  3. Ваша order_by конфигурация неверна, см. Код выше для версии, которая работает.
0 голосов
/ 28 ноября 2011

Вы можете попытаться определить Персона после Адреса с обратным указателем на Адрес - это создаст элемент массива:

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

Затем вы можете запросить:

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

Далее, еслиу вас много жителей по адресу, который вы можете отфильтровать, используя объединение:

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...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...