Отношение «многие к одному» возвращает объект «Нет»: SqlAlchemy

Я пытаюсь написать класс Schedule, который содержит записи вроде этого: … session, base, engine declaration где-то здесь …

class Schedule(Base): __tablename__ = 'schedule' id = Column(Integer, primary_key=True) # and here i need ref to Station class station_id = Column(Integer, ForeignKey('station.id')) station = relationship('Station') # Also tried Station arr_time = Column(Time) def __init__(self, station_name, arrive_time): self.metadata.create_all() self.arrive_time = arrive_time # And now I'm trying to find station object by a given name # and add ref to it in self.station. # The selection of a station works properly here: station = session.query(Station).filter(Station.name == station_name).first() # But on this statement I get an error: None object has no method 'append' self.station.append(station) session.add(self) session.commit() 

После этого я реализую класс 'Station'

 class Station(Base): __tablename__ = 'stations' id = Column(Integer, primary_key=True) name = Column(String) def __init__(self, name): self.name = name 

Поэтому, когда я пытаюсь добавить новую запись Schedule, я получаю сообщение об ошибке:

 AttributeError: 'NoneType' object has no attribute 'append' 

Случай «один ко многим» (где внешний ключ в первом классе и отношения во втором) работает правильно.

Что случилось с моим кодом?

Обновление: также попытался пример из документации:

 engine = create_engine('sqlite:///:memory:') Base = declarative_base(engine) session = sessionmaker(bind=engine)() class Parent(Base): __tablename__ = 'parent' id = Column(Integer, primary_key=True) child_id = Column(Integer, ForeignKey('child.id')) child = relationship("Child") class Child(Base): __tablename__ = 'child' id = Column(Integer, primary_key=True) if __name__ == '__main__': Base.metadata.create_all() parent = Parent() session.add(parent) child = Child() session.add(child) print(hasattr(Parent, 'child')) print(hasattr(parent, 'child')) print(type(Parent.child)) print(type(parent.child)) 

Я получил:

  >>> True >>> True >>> <class 'sqlalchemy.orm.attributes.InstrumentedAttribute'> >>> <class 'NoneType'> 

    У меня это получилось)) Проблема заключалась в том, что по умолчанию флаг uselist в конструкторе отношения задан для True . Но – я действительно не понимаю, почему это не написано в документации – в случае отношения «много-к-одному» этот флаг установлен для False .

    Итак, чтобы решить мою проблему, мне просто нужно изменить это:

     station = relationship("Station", uselist=True) 

    или использовать в конструкторе:

     self.station = station 

    Это полностью решает мою проблему.

    У меня была аналогичная проблема. Я думаю, проблема заключается в том, что отношения не срабатывают, пока вы не добавите и не зафиксируете.

     engine = create_engine('sqlite:///:memory:') Base = declarative_base(engine) session = sessionmaker(bind=engine)() class Parent(Base): __tablename__ = 'parent' id = Column(Integer, primary_key=True) child_id = Column(Integer, ForeignKey('child.id')) child = relationship("Child") class Child(Base): __tablename__ = 'child' id = Column(Integer, primary_key=True) if __name__ == '__main__': Base.metadata.create_all() parent = Parent() session.add(parent) child = Child() session.add(child) session.commit() # IMPORTANT: this is necessary for relationship to work print(hasattr(Parent, 'child')) print(hasattr(parent, 'child')) print(type(Parent.child)) print(type(parent.child)) 

    Единственная строка, которую я добавил, это

      session.commit() # IMPORTANT: this is necessary for relationship to work 
     station = session.query(Station).filter(Station.name == station.name).first() 

    self.station отсутствует.

    Попробуйте использовать отладчик или просто print station , print self.station

    Изменить: Области переменной класса:

    Существует два способа для класса vars:

    1. Переменная экземпляра – при использовании self это называется переменной экземпляра и тем самым для каждого экземпляра этого класса у вас будет копия переменной.

    2. Атрибут класса – в вашем случае это Schedule.station, он принадлежит классу, а не экземплярам класса.

    Пожалуйста, обратитесь к Документам об импространстве, это очистит вашу проблему.