Многозначные отношения в SQLAlchemy - PullRequest
0 голосов
/ 09 ноября 2018

У меня проблемы с отношениями «многие к одному» между моими моделями SQLAlchemy. Соотношение между ChangeOrder (много) и Contract (один) хорошо, но то, что между LineItem (много) и ChangeOrder (один) не работает.

Я испробовал оба подхода, предложенные в базовых отношениях документах, и оба не удаются для отношений LineItem - ChangeOrder.

# 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
...