5

次のようなレコードを含む Schedule クラスを作成しようとしています: ... セッション、ベース、エンジンの宣言はここのどこかに...

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

その後、クラス「ステーション」を実装します

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

    def __init__(self, name):
         self.name = name

そのため、新しいスケジュール レコードを追加しようとすると、エラーが発生します。

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

1 対多の場合 (最初のクラスに外部キーがあり、2 番目のクラスにリレーションシップがある場合) は正しく機能します。

コードの何が問題になっていますか?

更新: ドキュメントからの例も試しました:

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

3 に答える 3

2

同様の問題がありました。問題は、追加してコミットするまで関係がトリガーされないことだと思います。

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
于 2016-06-14T22:08:04.617 に答える
0
station = session.query(Station).filter(Station.name == station.name).first()

self.stationはなしです....

デバッガーを使用するか、単にprint stationprint self.station

編集: クラス変数のスコープ:

クラス スコープ変数には 2 つの方法があります。

  1. インスタンス変数 - 自己を使用する場合、これはインスタンス変数と呼ばれ、それにより、そのクラスの各インスタンスに変数のコピーが作成されます。

  2. クラス属性 - あなたの場合、それはクラスのインスタンスではなく、クラスによって所有されている Schedule.station です。

問題を解決する名前空間に関するドキュメントを参照してください。

于 2013-10-14T08:44:56.373 に答える