我有大量数据,来自不同的采集系统。这是用 SQLalchemy 定义的 ORM:
class DataTable(Base):
__tablename__ = "data_table"
id: Mapped[int] = mapped_column(primary_key=True)
system_id: Mapped[int] = mapped_column(ForeignKey("system.id"))
system: Mapped["System"] = relationship()
data_feature: Mapped[int] = mapped_column(String(32))
class System(Base):
__tablename__ = "system"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(16))
system_feature: Mapped[str] = mapped_column(String(16))
系统已经存在于数据库中。现在我想将大量数据(~200k)放在DB上。每个数据行都带有系统名称。我想在数据库上传期间将这些名称解析为相应的 ID。目前,我在客户端使用 pandas.merge 解析系统名称。我从 myData pandas.DataFrame 中删除系统名称列并重命名 id 列(源于系统表)
system_table = session.execute(select(System.id, System.name)).all()
system_table_df = pandas.DataFrame(system_table)
new_data = myData.merge(system_table_df, left_on='system_name',
right_on='name').drop(['system_name', 'name'], axis=1)
new_data.rename(columns={'id': 'system_id'}, inplace=True)
然后我可以将数据插入数据库。
session.execute(insert(DataTable).values(myData.to_dict(orient='records'))
session.commit()
有没有办法在数据库上解析系统ID?
我尝试使用 insert().returning(),这使我非常接近,但并没有完全完成工作。我不知道如何从 myData 捕获 system_name 属性并在 where 子句中使用它。
session.execute(
insert(DataTable).values(
system_id=select(System.id).where(System.name == "???")
).returning(DataTable), myData.to_dict(orient="records"))
另一种方法是使用 session.add(),如如何使用 sqlalchemy 创建外键引用。也没解决。
传递一个执行查找的子查询到插入的
.values()
方法
subq = (
sa.select(System.id).where(System.name == sa.bindparam('system')).scalar_subquery()
)
with Session.begin() as s:
insert = sa.insert(DataTable).values(system_id=subq)
s.execute(insert, dts)
这将发出如下 SQL:
INSERT INTO data_table (system_id, data_feature) VALUES ((SELECT system.id
FROM system
WHERE system.name = ?), ?)