簡體   English   中英

(Alembic、SQLAlchemy)我可以在遷移腳本中將數據從非分區鍵復制到分區鍵嗎?

[英](Alembic, SQLAlchemy) Can I copy data from non partitioned key to a partitioned one in the migration script?

我有一個表需要分區,但是由於在創建表時沒有添加postgresql_partition_by所以我試圖:

  • 創建一個與原始分區表相似的新分區表。
  • 將數據從舊數據移動到新數據。
  • 放下原來的。
  • 重命名新的。 那么將數據從舊表移動到新表的最佳做法是什么?

我試過了,但沒用

COPY partitioned_table 
FROM original_table;

也試過

INSERT INTO partitioned_table (column1, column2, ...)
SELECT column1, column2, ...
FROM original_table;

但兩者都不起作用:(注意我正在使用 Alembic 生成遷移腳本也正在使用來自 Python 的 sqlalchemy

基本上你有下面描述的兩種情況。

- 表很大,需要把數據拆分成幾個分區

- 該表獲得第一個分區,您為新數據添加新分區

讓我們將此設置用於未分區的表

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);

現在原始表獲得分區表的第一個分區。 即不執行數據復制。

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)                                          |

類似的答案,這里有一些分區創建自動化的提示

在嘗試了一些事情之后,解決方案是:

INSERT INTO new_table(fields ordered as the result of the select statement) SELECT * FROM old_table

不知道是否有更簡單的方法來排序字段,但我嘗試從這些選項在 DBEver 中插入一行然后得到像這些步驟這樣的名稱

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM