Я хочу иметь таблицу, 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
, но для моей ситуации это нежелательно.