私は最近この問題にぶつかり、数日間立ち往生しています。基本的に、ここで重要な 2 つのテーブルは「Activity」と「Goal」です。Activity は、Goal の単一の親です。ゴールにはちょうど 1 つの親があり、アクティビティには 1 つ以上のゴールの子があります。
class Activity(Base, Table):
__tablename__ = 'activity'
pk_id = Column(Integer, primary_key=True)
name = Column(String)
wave = Column(Integer)
enabled = Column(Boolean)
goals = relationship("Goal", backref='activity', single_parent=True, cascade="all,delete-orphan")
activity_tags = relationship("ActivityTags", backref='tag_activity', cascade="all,delete-orphan")
と
class Goal(Base, Table):
__tablename__ = 'goal'
pk_id = Column(Integer, primary_key=True)
activity_id = Column(Integer, ForeignKey('activity.pk_id'))
category_id = Column(Integer, ForeignKey('category.pk_id'))
name = Column(String)
minutes_expected = Column(Integer)
date_last_invoked = Column(Date)
date_last_invalidated = Column(Date)
enabled = Column(Boolean)
milestones = relationship("Milestone", backref='goal', single_parent=True, cascade="all,delete-orphan")
ここで、Activity オブジェクトを作成すると (1 つの Goal 子オブジェクトが作成されます)、次のエラーが発生します。
Traceback (most recent call last):
File "unit.py", line 49, in wrapper
r = func(*args, **kwargs)
File "unit.py", line 158, in testActivityWaveOverdue
a = Activity(c, 'Pull-Ups', wave)
File "<string>", line 4, in __init__
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 98, in initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "/home/me/dev/coach/coach/activity.py", line 64, in __init__
self.add_goal(category, 'maintenance')
File "/home/me/dev/coach/coach/activity.py", line 190, in add_goal
return Goal(self, category, name, minutes_expected)
File "<string>", line 4, in __init__
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 98, in initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "/home/me/dev/coach/coach/goal.py", line 76, in __init__
db.session.commit()
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 656, in commit
self.transaction.commit()
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 314, in commit
self._prepare_impl()
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 298, in _prepare_impl
self.session.flush()
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1583, in flush
self._flush(objects)
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1636, in _flush
is_orphan = _state_mapper(state)._is_orphan(state) and state.has_identity
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 1237, in _is_orphan
state, key, optimistic=bool(state.key)):
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/instrumentation.py", line 331, in has_parent
return self.get_impl(key).hasparent(state, optimistic=optimistic)
File "/home/me/dev/coach/.venv/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 349, in hasparent
assert self.trackparent, "This AttributeImpl is not configured to track parents."
AssertionError: This AttributeImpl is not configured to track parents.
アクティビティの初期化コードは次のとおりです。
def __init__(self, category, name, wave):
self.name = name
self.wave = wave
self.enabled = True
db.session.add(self)
db.session.commit()
self.add_goal(category, 'maintenance')
def add_goal(self, category, name, minutes_expected=30):
return Goal(self, category, name, minutes_expected)
そしてゴールのそれ:
def __init__(self, activity, category, name, minutes_expected):
self.activity_id = activity.pk_id
self.category_id = category.pk_id
self.name = name
self.minutes_expected = minutes_expected
self.date_last_invoked = START_OF_TIME
self.date_last_invalidated = START_OF_TIME
self.enabled = True
db.session.add(self)
db.session.commit()
上記に含めてほしいことが他にあれば教えてください - 投稿を必要以上に大きくしたくなかったので、問題に関連すると思われるものだけを含めました.
最後に、Activity と Goal が継承する "Table" スーパークラスは、単純に補助/ヘルパー メソッドを提供します。