В Sqlalchemy Странное поведение при добавлении объекта дважды в атрибуте отношения класса - PullRequest
0 голосов
/ 18 октября 2011

Я сталкиваюсь с некоторыми странными проблемами при изучении SQLAlchemy.Я использую его версию 0.7.2.Это мои тестовые классы:

    class User(Base):
        __tablename__ = 'users'

        id = Column('user_id',Integer,primary_key = True)
        name = Column('user_name',String(20))

        addresses = relationship("Address",backref="user")

        def __repr__(self):
              return "<User(%s)>" % self.name

    class Address(Base):
          __tablename__ = 'addresses'

          id = Column('adress_id',Integer,primary_key = True)
          address = Column('address',String(30))
          user_id = Column('user_id',ForeignKey('users.user_id'))

          def __repr__(self):
               return "<Address(%s)>" % self.address
  1. Я случайно запустил свой основной файл дважды, что заставило выполнить следующий код дважды

    Session = sessionmaker()
    session = Session(bind=engine)
    q=session.query(User)
    a=q.get(3)
    a.addresses.append(Address(address='myaddress'))
    session.flush()
    print a.addresses[0].id,a.addresses[0].address
    

    Сначала я подумал, что a.addressesполучил бы два объекта адреса с 'myaddress'.Но на самом деле есть только один объект, у которого address_id был обновлен.Я имею в виду, что когда я запускал файл первым, он печатал

    1,'myaddress'
    
    and then in second run it printed
    
    2,'myaddress'
    

Я подтвердил существование только объекта Address, напечатав a.addresses, и он показывает только объект в нем.

Не следует ли добавить второй объект Address в a.addresses при добавлении вместо обновления идентификатора существующего объекта адреса?

Заметьте, что не выполняется команда session.commit ().Я просто запустил файл дважды и заметил это поведение.

Редактировать: Добавлен код, который создает новый сеанс и отвечает за проблему, как предложено Ван ниже в ответе

1 Ответ

0 голосов
/ 19 октября 2011

Этого нельзя увидеть в вашем коде, но я предполагаю, что код, который выполняется дважды, также выполняется в двух разных сеансах .Это объясняет все побочные эффекты , которые вы наблюдаете:

  • только один адрес: потому что второй сеанс не знает о первом (не зафиксирован)
  • адрес ID увеличивается: это происходит из-за flush() в первом сеансе, где идентификатор назначается объекту.Это не обновление предыдущего Address, а скорее присвоение ID новому Address.
...