簡體   English   中英

SQLAlchemy:如何處理與其他表的外鍵鄰接表?

[英]SQLAlchemy: How to handle adjacency list with foreign key to other table?

讓我們考慮以下最小示例:

  • 帶有 id 和名稱的測量表。
  • 帶有 id 和名稱的模擬表。 此外,還有一個外鍵引用模擬所基於的測量的 id,以及一個外鍵引用模擬所基於的其他模擬。

我想出的代碼的最小工作示例如下:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import sessionmaker, scoped_session, relationship

engine = create_engine('postgresql://postgres:12345@localhost:5432/Example')

Session = scoped_session(sessionmaker(bind=engine))

Base = declarative_base()

class Measurement(Base):
    __tablename__ = 'measurement'

    id = Column(Integer, primary_key=True)
    name = Column(String)

    simulation = relationship('Simulation', back_populates='measurement', uselist=False)


class Simulation(Base):
    __tablename__ = 'simulation'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    measurement_id = Column(Integer, ForeignKey('measurement.id', onupdate='CASCADE', ondelete='CASCADE'))
    parent_simulation_id = Column(Integer, ForeignKey('simulation.id'), index=True)

    measurement = relationship('Measurement', back_populates='simulation')
    parent_simulation = relationship('Simulation', remote_side=id, backref='child_simulation')

Base.metadata.create_all(engine)

但是現在我使用代碼有一個奇怪的行為。 有了第一個測試代碼,一切都很順利:

sess = Session()

measurement = Measurement(name='Measurement_1')
sess.add(measurement)
sess.commit()

simulation1 = Simulation(name='Simulation_1', measurement=measurement, parent_simulation=None)
simulation2 = Simulation(name='Simulation_1.1', measurement=measurement, parent_simulation=simulation1)

sess.add_all((simulation2, simulation1))
sess.commit()

正如所料,output 如下:

 id |      name      | measurement_id | parent_simulation_id
----+----------------+----------------+----------------------
  1 | Simulation_1   |              1 |
  2 | Simulation_1.1 |              1 |                    1

但是,如果我更改測試代碼,以便在第二個模擬被初始化之前刷新第一個模擬......

sess = Session()

measurement = Measurement(name='Measurement_1')
sess.add(measurement)
sess.commit()

simulation1 = Simulation(name='Simulation_1', measurement=measurement, parent_simulation=None)
sess.add_all((simulation1, ))
sess.flush()

simulation2 = Simulation(name='Simulation_1.1', measurement=measurement, parent_simulation=simulation1)
sess.add_all((simulation2, ))
sess.commit()

...結果不再像預期的那樣:

 id |      name      | measurement_id | parent_simulation_id
----+----------------+----------------+----------------------
  1 | Simulation_1   |                |
  2 | Simulation_1.1 |              1 |                    1

我究竟做錯了什么? 為什么我進入第二個模擬后第一個模擬的measurement_id消失了?

我不確定我是否完全理解您的數據 model,但是對於沒有引用或引用一個測量的模擬,您不需要

measurement = relationship('Measurement', back_populates='simulation')

在模擬class,你呢? 嘗試消除這種關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM