SQLAlchemy: зеркало неосновного столбца из другой таблицы - PullRequest
0 голосов
/ 17 июня 2020

Я хочу иметь таблицу, Goals, которая находится во взаимосвязи «один ко многим» с другой таблицей, Hints, то есть одна подсказка может быть для многих целей, но каждая цель имеет одну подсказку. Теперь я хочу, чтобы Goals отражал два столбца в Hints. Hints имеет столбцы id (основной) и penalty (неуникальный), и я хочу, чтобы Goals имел столбцы hint_id и hint_penalty, которые отражают столбцы связанной подсказки. Я понимаю, как можно отразить id, поскольку это первичный ключ в Hint, и использование отношения прекрасно обновляет его при гриппе sh, но penalty, похоже, не распространяется.

Вот что я имею в виду:

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


Base = declarative_base()


class Hint(Base):
    __tablename__ = 'hint'
    id = Column(Integer, primary_key=True)
    penalty = Column(Integer, nullable=False)

class Goal(Base):
    __tablename__ = 'goal'
    id = Column(Integer, primary_key=True)
    hint_penalty = Column(
        Integer, ForeignKey('hint.penalty'))
    hint_id = Column(Integer, ForeignKey('hint.id'))
    hint = relationship(
        # this leaves hint_penalty blank
        Hint, foreign_keys=[hint_id],
        # this raises sqlalchemy.exc.AmbiguousForeignKeysError
        #  Hint, foreign_keys=[hint_id, hint_penalty],
        backref=backref('goals', uselist=True))


engine = create_engine('sqlite://', echo=True)
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine)()

g1 = Goal()
h1 = Hint(penalty=1, goals=[g1])
h2 = Hint(penalty=1)
g2 = Goal(hint=h2)

session.add(h1)
session.add(h2)
session.commit()

print((
    'g1.hint_id = {hid1}\n'
    'g1.hint_penalty = {hp1}\n'
    'g2.hint_id = {hid2}\n'
    'g2.hint_penalty = {hp2}\n'
).format(
    hid1=g1.hint_id,
    hp1=g1.hint_penalty,
    hid2=g2.hint_id,
    hp2=g2.hint_penalty))

В каком бы порядке я ни создавал цель и подсказку, goal.hint_penalty всегда None:

g1.hint_id = 1
g1.hint_penalty = None
g2.hint_id = 2
g2.hint_penalty = None

Как я могу размножить hint.penalty на goal.hint_penalty при гриппе sh?

Я, конечно, знаю, что могу получить к нему доступ через goal.hint.penalty, но для моей ситуации это нежелательно.

1 Ответ

0 голосов
/ 18 июня 2020

Добавление соответствующего primaryjoin в отношение сделало работу:

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


Base = declarative_base()


class Hint(Base):
    __tablename__ = 'hint'
    id = Column(Integer, primary_key=True)
    penalty = Column(Integer, nullable=False)

class Goal(Base):
    __tablename__ = 'goal'
    id = Column(Integer, primary_key=True)
    hint_penalty = Column(
        Integer, ForeignKey('hint.penalty'))
    hint_id = Column(Integer, ForeignKey('hint.id'))
    hint = relationship(
        Hint,
        primaryjoin="and_(Hint.penalty == foreign(Goal.hint_penalty), "
                    "Hint.id == foreign(Goal.hint_id))",
        backref=backref('goals', uselist=True))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...