sqlalchemy:从另一个表镜像非主列

hyrbngr7  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(191)

我想要张table, Goals ,它与另一个表处于一对多关系中, Hints ,这意味着一个提示可以用于多个目标,但每个目标都有一个提示。现在我想要 Goals 以反映 Hints . Hints 有列 id (主要)和 penalty (非唯一)我想要 Goals 要有列 hint_id 以及 hint_penalty 这反映了那些链接的提示。我明白 id 可以镜像,因为它是 Hint 使用关系很好地更新了flush,但是 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.penaltygoal.hint_penalty 冲水时?
我当然知道我可以通过 goal.hint.penalty 但就我的情况来说,这是不可取的。

jrcvhitl

jrcvhitl1#

添加适当的 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))

相关问题