【问题标题】:(Alembic, SQLAlchemy) Can I copy data from non partitioned key to a partitioned one in the migration script?(Alembic、SQLAlchemy)我可以在迁移脚本中将数据从非分区键复制到分区键吗?
【发布时间】:2023-01-27 02:46:11
【问题描述】:

我有一个表需要分区,但由于在创建表时未添加 postgresql_partition_by,所以我尝试:

  • 创建一个与原始表相似的新分区表。
  • 正在将数据从旧数据移动到新数据。
  • 放下原来的那个。
  • 重命名新的。 那么将数据从旧表移动到新表的最佳做法是什么?

我试过了,但没用 COPY partitioned_table FROM original_table; 也试过INSERT INTO partitioned_table (column1, column2, ...) SELECT column1, column2, ... FROM original_table; 但两者都不起作用:(

注意我正在使用 Alembic 生成迁移脚本也正在使用 Python 中的 sqlalchemy

【问题讨论】:

  • didn't work 不是错误消息 - 请说明问题

标签: database postgresql sqlalchemy partitioning alembic


【解决方案1】:

基本上,您在下面描述了两种情况。

- 表很大,需要把数据拆分成几个分区

- 该表获得第一个分区,您为新数据添加新分区

让我们将此设置用于未分区桌子

create table jdbn.non_part 
 (id int not null, name varchar(100));

insert into jdbn.non_part (id,name)
SELECT  id, 'xxxxx'|| id::varchar(20) name
from generate_series(1,1000) id;

该表包含从 1 到 1000 的 id,对于第一种情况,您需要将它们分成两个分区,每个分区 500 行。

创建分区表

具有与原始表相同的结构和约束

create table jdbn.part  
(like jdbn.non_part INCLUDING DEFAULTS INCLUDING CONSTRAINTS)
PARTITION BY RANGE (id);

添加分区

覆盖当前数据

create table jdbn.part_500 partition of jdbn.part
for values from (1) to (501); /* 1 <= id < 501 */

create table jdbn.part_1000 partition of jdbn.part
for values from (501) to (1001);  

用于未来数据(根据需要)

create table jdbn.part_1500 partition of jdbn.part
for values from (1001) to (1501); 

使用insert复制数据

请注意,这种方法复制数据意味着您需要两倍的空间并可能清理旧数据。

insert into jdbn.part (id,name)
select id, name from jdbn.non_part;

检查分区修剪

注意只访问part_500分区

EXPLAIN SELECT * FROM jdbn.part WHERE id <= 500;

QUERY PLAN                                                      |
----------------------------------------------------------------+
Seq Scan on part_500 part  (cost=0.00..14.00 rows=107 width=222)|
  Filter: (id <= 500)                                           |

第二个选项 - 将数据移动到一个分区

如果您可以接受一个(大)初始分区,则可以使用第二种方法

创建分区表

同上

附加表作为分区

ALTER TABLE jdbn.part ATTACH PARTITION jdbn.non_part
   for values from (1) to (1001);

现在原始表获得分区表的第一个分区。 IE。不执行数据复制。

EXPLAIN SELECT * FROM jdbn.part WHERE id <= 500;
QUERY PLAN                                                     |
---------------------------------------------------------------+
Seq Scan on non_part part  (cost=0.00..18.50 rows=500 width=12)|
  Filter: (id <= 500)                                          |

类似的答案和一些分区创建自动化的提示here

【讨论】:

    猜你喜欢
    • 2016-12-23
    • 1970-01-01
    • 2018-09-20
    • 2018-09-02
    • 2014-03-28
    • 2014-02-05
    • 2020-05-24
    • 2012-12-05
    • 1970-01-01
    相关资源
    最近更新 更多