我尝试使用sqlalchemy核心在范围列上的postgres数据库中拆分行,但我似乎无法在不将临时信息存储在内存中的情况下弄清楚如何这样做。
表/数据的基本结构:
import psycopg2.extras as pgx
import sqlalchemy as sa
import sqlalchemy.dialects.postgresql as sap
table = sa.Table(
'table', sa.MetaData(),
sa.Column('value', sa.Integer),
sa.Column('range', sap.INT8RANGE))
conn.execute(table.insert(), [{'value': 1, 'range': pgx.NumericRange(1, None)}])
我尝试做的是将行拆分为两行,具有不同的范围值。我可以通过更新返回来执行此操作,然后以下列方式在结果中单独插入:
split_point = 3
left_range = sa.func.int8range(sa.func.lower(table.c.range), split_point)
return_columns = [c for c in table.c]
return_keys = [c.name for c in return_columns]
capped_rows = conn.execute(
table.update()
.where(table.c.range.contains(sa.cast(split_point, sa.BigInteger)))
.values({'range': left_range})
.returning(return_columns))
new_rows = []
for row in capped_rows:
new_row = dict(zip(return_keys, row))
new_row['range'] = pgx.NumericRange(split_point, None)
new_rows.append(new_row)
if new_rows:
conn.execute(table.insert(), new_rows)
这会产生表格的预期输出:
expected = [
{'value': 1, 'range': pgx.NumericRange(1, 3)},
{'value': 1, 'range': pgx.NumericRange(3, None)},
]
不可思议地,这样做需要我在new_rows列表中将大量数据加载到内存中,这也要求我将数据移入和移出数据库。
有没有办法通过将更新链接到插入或者在服务器端执行所有操作来实现相同的结果?
我尝试过使用table.insert()。from_select,但我可以'似乎找到了有效的from_select内容。