SQLAlchemy中的多对一关系

时间:2018-11-09 19:42:58

标签: sqlalchemy foreign-keys

我在处理SQLAlchemy模型之间的多对一关系时遇到麻烦。 ChangeOrder(很多)和Contract(一个)之间的关系很好,但是LineItem(很多)和ChangeOrder(一个)之间的关系不起作用。< / p>

我已经尝试了basic relationships文档中建议的两种方法,但都无法实现LineItemChangeOrder之间的关系。

# using back_populates
class Contract(Base):
    __tablename__ = "contract"
    id = Column(Integer, primary_key=True)
    change_orders = relationship("ChangeOrder", back_populates="contract")


class ChangeOrder(Base):
    __tablename__ = "changeorder"
    id = Column(Integer, primary_key=True)
    line_items = relationship("LineItem", back_populates="change_order")
    contract_id = Column(Integer, ForeignKey("contract.id"))
    contract = relationship("Contract", back_populates="change_orders")


class LineItem(Base):
    __tablename__ = "lineitem"
    id = Column(Integer, primary_key=True)
    change_order_id = Column(Integer, ForeignKey("changeorder.id"))
    change_order = relationship("ChangeOrder", back_populates="line_items")


def test_insert_change_order(db_session, item):
    c = Contract()
    db_session.add(c)
    db_session.commit()
    co = ChangeOrder(contract_id=c.id)
    db_session.add(co)
    db_session.commit()
    row = db_session.query(Contract).get(c.id)
    assert len(row.change_orders) == 1  # this Many-to-One works
    li = LineItem(change_order_id=co.id)
    db_session.add(li)
    db_session.commit()
    row = db_session.query(ChangeOrder).get(co.id)
    assert len(row.line_items) == 1  # this Many-to-One does not

我也尝试了backref方法,但是它有同样的问题。

# using backref
class LineItem(Base):
    __tablename__ = "lineitem"
    id = Column(Integer, primary_key=True)
    change_order_id = Column(Integer, ForeignKey("changeorder.id"))
    change_order = relationship("ChangeOrder", backref="line_items")


class ChangeOrder(Base):
    __tablename__ = "changeorder"
    id = Column(Integer, primary_key=True)
    contract_id = Column(Integer, ForeignKey("contract.id"))
    contract = relationship("Contract", backref="change_orders")


class Contract(Base):
    __tablename__ = "contract"
    id = Column(Integer, primary_key=True)

conftest.py

import pytest
from flask_sqlalchemy import SQLAlchemy

from frontend.app import app


@pytest.fixture
def testapp():
    db = SQLAlchemy()
    app.config["SQLALCHEMY_ECHO"] = True
    with app.app_context():
        db.create_all()
        yield app
        db.session.remove()
        db.drop_all()


@pytest.fixture(scope="session")
def database():
    db = SQLAlchemy()
    with app.app_context():
        db.create_all()
        yield db


@pytest.fixture(scope="session")
def _db(database):
    return database

0 个答案:

没有答案