gpt4 book ai didi

python - 将数据从一个 sqlalchemy session 复制到另一个

转载 作者:行者123 更新时间:2023-12-05 08:55:29 26 4
gpt4 key购买 nike

我有一个包含三个表(A、B 和 C)的 sqlalchemy 模式,它们通过一对多的外键关系(A->B 之间)和(B->C 之间)关联,以 SQLite 作为后端。我创建了单独的数据库文件来存储数据,每个文件都使用完全相同的 sqlalchemy 模型并运行相同的代码来将数据放入其中。

我希望能够从所有这些单独的数据库中复制数据并将它们放入一个新的数据库文件中,同时保留外键关系。我尝试了以下代码将数据从一个文件复制到一个新文件:

import sqlalchemy
from sqlalchemy.ext import declarative
from sqlalchemy import Column, String, Integer
from sqlalchemy import orm, engine

Base = declarative.declarative_base()
Session = orm.session_maker()

class A(Base):
__tablename__ = 'A'

a_id = Column(Ingeter, primary_key=True)
adata = Column(String)
b = orm.relationship('B', back_populates='a', cascade='all, delete-orphan', passive_deletes=True)


class B(Base):
__tablename__ = 'B'

b_id = Column(Ingeter, primary_key=True)
a_id = Column(Integer, sqlalchemy.ForeignKey('A.a_id', ondelete='SET NULL')
bdata = Column(String)
a = orm.relationship('A', back_populates='b')
c = orm.relationship('C', back_populates='b', cascade='all, delete-orphan', passive_deletes=True)

class C(Base):
__tablename__ = 'C'

c_id = Column(Ingeter, primary_key=True)
b_id = Column(Integer, sqlalchemy.ForeignKey('B.b_id', ondelete='SET NULL')
cdata = Column(String)
b = orm.relationship('B', back_populates='c')


file_new = 'file_new.db'
resource_new = 'sqlite:////%s' % file_new.lstrip('/')
engine_new = sqlalchemy.create_engine(resource_new, echo=False)
session_new = Session(bind=engine_new)

file_old = 'file_old.db'
resource_old = 'sqlite:////%s' % file_old.lstrip('/')
engine_old = sqlalchemy.create_engine(resource_old, echo=False)
session_old = Session(bind=engine_old)

for arow in session_old.query(A):
session_new.add(arow) # I am assuming that this will somehow know to copy all the child rows from the tables B and C due to the Foreign Key.

运行时,出现错误“对象 '' 已附加到 session '2'(这是 '1')”。关于如何使用 sqlalchemy 和 session 执行此操作的任何指示?我还想保留每个数据库中的外键关系。

用例是数据首先在非联网机器本地生成,然后聚合到云端的中央数据库中。虽然数据将在 SQLite 中生成,但合并可能发生在 MySQL 或 Postgres 中,尽管这里为简单起见一切都发生在 SQLite 中。

最佳答案

首先,你得到这个错误的原因是因为 arow 实例仍然被 session_old 跟踪,所以 session_new 将拒绝处理它。您可以将它从 session_old 中分离出来:

session_old.expunge(arow)

这将允许您毫无问题地将 arow 添加到 session_new,但是您会注意到没有任何内容被插入到 file_new 中。这是因为 SQLAlchemy 知道 arow 是持久化的(意味着数据库中有一行对应这个对象),当你分离它并将它添加到 session_new 时,SQLAlchemy 仍然认为它是持久的,所以它不会被再次插入。

这是Session.merge的地方进来。一个警告是它不会合并未加载的关系,因此您需要预先加载所有要合并的关系:

query = session_old.query(A).options(orm.subqueryload(A.b),
orm.subqueryload(A.b, B.c))
for arow in query:
session_new.merge(arow)

关于python - 将数据从一个 sqlalchemy session 复制到另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45802620/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com