Python 使用'sqlalchemy``insert`批量插入相关对象

Python 使用'sqlalchemy``insert`批量插入相关对象,python,postgresql,sqlalchemy,Python,Postgresql,Sqlalchemy,我正在使用sqlalchemy将数据插入表中。我关心的事情: 我希望插入大量数据,以便尽量减少数据库执行的次数 将有重复的条目,这是预期的,因此我将在冲突中使用,不使用任何内容(我使用的是postgres) 举个简单的例子,假设我有两个表: 来自sqlalchemy导入列,整数,外键,字符串 Base=声明性_Base() 班级地址(基本地址): __tablename_u=“地址” id=列(整数,主键=True) 街道=列(字符串) 数字=列(整数) 班级人员(基本) __tablena

我正在使用sqlalchemy将数据插入表中。我关心的事情:

  • 我希望插入大量数据,以便尽量减少数据库执行的次数
  • 将有重复的条目,这是预期的,因此我将在冲突中使用
    ,不使用任何内容(我使用的是postgres)
举个简单的例子,假设我有两个表:

来自sqlalchemy导入列,整数,外键,字符串
Base=声明性_Base()
班级地址(基本地址):
__tablename_u=“地址”
id=列(整数,主键=True)
街道=列(字符串)
数字=列(整数)
班级人员(基本)
__tablename_u=“people”
id=列(整数,主键=True)
名称=列(字符串)
address\u id=列(整数,ForeignKey(“addresses.id”)
地址=关系(“地址”)
我可以使用以下工具轻松地批量处理所有
地址
插入:

来自sqlalchemy.dialogs.postgresql导入插入
值=[{“街道”:“主要”、“编号”:1},{“街道”:“主要”、“编号”:2}]
语句=插入(地址).values(值).on_conflict_do_nothing()
session.execute(语句)
问题是我该如何对待
?我正在努力为
“地址”
提供什么

values=[{“name”:“John”,“address”:???}]
语句=插入(Person).values(values).on\u conflict\u do\u nothing()
session.execute(语句)

我假设我需要
地址
对象,但我不知道从那里去哪里?

不要使用
地址
,因为它不是一个SQL字段。你可以使用它来获取刚刚插入的地址的id,然后基于此设置
值[0]['Address\u id']
。类似的方法应该可以:

来自sqlalchemy.dialogs.postgresql导入插入
值=[{“街道”:“主要”、“编号”:1},{“街道”:“主要”、“编号”:2}]
语句=插入(地址)\
.价值观(价值观)\
.returning(Address.id)\
.关于冲突什么都不做
address\u id=[会话中address\u id的address\u id,执行(语句)]
value=[{“name”:“John”,“address_id”:address_id[0]}]
语句=插入(Person).values(values).on\u conflict\u do\u nothing()
session.execute(语句)
解释

insert()。在“冲突”方面,与添加的SQLAlchemy层相比,您正相对接近PostgreSQL的裸机。这并不是一件坏事,这当然是您拥有最多控制权和速度最快的地方,但这确实意味着您需要仔细考虑SQLAlchemy添加了哪些字段,以及数据库直接反映哪些字段

在您的情况下,只有
id
name
address\u id
是实际的数据库列。如果执行
SELECT*FROM people
,它们是应该显示的唯一列。相反,
address
是由SQLAlchemy添加的,它为您提供了一个到
address
实例的id
add的直接链接ress_id
,但在水下,如果需要,会对数据库执行不同的调用以获取它


如果您有一个id为1的
地址
,那么设置
john.Address=1
不起作用,因为1不是地址,它是一个数字。但是,设置
john.Address\u id=1
,确实起作用,因为您直接设置了一个字段。如果您使用的是完整的ORM(您不是),SQLAlchemy不鼓励这样做,因为您在他们的生态系统之外执行此操作。如果您运行
john.address=address.query.get(1)
,您将整个Address对象分配给Address,SQLAlchemy在内部将
Address\u id
更新为1。

不要使用
Address
,因为它不是SQL字段。您可以使用来获取刚插入的地址的id,然后设置
值[0]['Address\u id']
基于此。类似的方法应该可以:

来自sqlalchemy.dialogs.postgresql导入插入
值=[{“街道”:“主要”、“编号”:1},{“街道”:“主要”、“编号”:2}]
语句=插入(地址)\
.价值观(价值观)\
.returning(Address.id)\
.关于冲突什么都不做
address\u id=[会话中address\u id的address\u id,执行(语句)]
value=[{“name”:“John”,“address_id”:address_id[0]}]
语句=插入(Person).values(values).on\u conflict\u do\u nothing()
session.execute(语句)
解释

insert()。在“冲突”方面,与添加的SQLAlchemy层相比,您正相对接近PostgreSQL的裸机。这并不是一件坏事,这当然是您拥有最多控制权和速度最快的地方,但这确实意味着您需要仔细考虑SQLAlchemy添加了哪些字段,以及数据库直接反映哪些字段

在您的情况下,只有
id
name
address\u id
是实际的数据库列。如果执行
SELECT*FROM people
,它们是应该显示的唯一列。相反,
address
是由SQLAlchemy添加的,它为您提供了一个到
address
实例的id
add的直接链接ress_id
,但在水下,如果需要,会对数据库执行不同的调用以获取它

如果您有一个id为1的
地址
,那么设置
john.Address=1
不起作用,因为1不是地址,它是一个数字。但是,设置
john.Address\u id=1
,确实起作用,因为您直接设置了一个字段。如果您使用的是完整的ORM(您不是),SQLAlchemy不鼓励这样做,因为您在他们的生态系统之外执行此操作。如果您运行
john.address=address.query.get(1)
,则将整个address对象分配给address,并且SQLAlchemy在内部将
address\u id
更新为1。