in.db
Python アプリケーションが起動したら、すべてのデータを からロードして に入れたいと思いますout.db
(そして、おそらく で変更を加えますout.db
)。を使っsession.merge(loaded_object)
ていますが、関連オブジェクトが保存されないのが難点です。
私のデータは単純な Person オブジェクトであり、それらの間に明らかな親子関係があります (多対多):
from sqlalchemy import create_engine, Column, String, Integer, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship, backref
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Person(Base):
__tablename__ = "people"
id = Column(Integer, primary_key=True)
name = Column(String)
def __init__(self, name):
self.name = name
def add_kid(self, kid):
Edge(kid=kid, parent=self)
return self
def get_kids(self):
return [edge.kid for edge in self.kid_edges]
def add_parent(self, parent):
Edge(kid=self, parent=parent)
return self
def get_parents(self):
return [edge.parent for edge in self.parent_edges]
def __repr__(self):
return "<Person(id={id}, name={name})>".format(id=str(self.id),
name=self.name)
class Edge(Base):
__tablename__ = "edges"
id = Column(Integer, primary_key=True)
kid_id = Column(Integer, ForeignKey("people.id"))
parent_id = Column(Integer, ForeignKey("people.id"))
kid = relationship("Person", primaryjoin="Edge.kid_id==Person.id",
backref=backref("parent_edges",
collection_class=set))
parent = relationship("Person", primaryjoin="Edge.parent_id==Person.id",
backref=backref("kid_edges",
collection_class=set))
def __init__(self, kid, parent):
self.kid = kid
self.parent = parent
次の方法でセッションを初期化します。
db_in_engine = create_engine("sqlite:///in.db", echo=True)
db_in_session_factory = sessionmaker(bind=db_in_engine)
db_in_session = db_in_session_factory()
db_out_engine = create_engine("sqlite:///out.db", echo=True)
db_out_session_factory = sessionmaker(bind=db_out_engine)
db_out_session = db_out_session_factory()
Base.metadata.create_all(db_out_engine)
問題は、人をマージすると、子供がマージされないことです:
people = db_in_session.query(Person).all()
db_out_session.merge(people[0])
db_out_session.commit() # related Edges, kids and parents of people[0] are not saved
リレーションシップと backref に cascade="merge" を追加しようとしましたが、うまくいきませんでした。People[0] のすべての子供/親と関連する Edge を強制的に保存する方法はありますか?