将新列添加到Postgres分区主表

时间:2012-04-05 11:53:14

标签: postgresql partitioning

我有一张桌子:

dw_readings(date_key, time_key, account_key, reading_value, consumption, processed_date) 

已按年date_key分区。我现在需要在主表中添加reading_id列以支持新功能,但是使用alter table语句似乎无法正常工作。应用alter添加新的reading_id列后,insert into dw_readings只会将reading_id设置为null,尽管insert中已设置了值声明;这可以通过Java JDBC和pgAdmin重现。但update语句设置reading_id正确,允许我设置列值。

使用以下声明

更改表格
ALTER dw_readings ADD COLUMN reading_id INTEGER;

我需要知道的是如何正确地将新列添加到分区表中,以便插入正常工作。

3 个答案:

答案 0 :(得分:2)

我设法在代码中追踪问题。问题与为分区创建的规则集有关。

    CREATE OR REPLACE RULE dw_readings_insert_y2009 AS
       ON INSERT TO dw_readings
       WHERE new.date_key >= 20090101 AND new.date_key < 20100101
       DO INSTEAD 
    INSERT INTO dw_readings_y2009 (date_key, time_key, account_key, reading_value, consumption, processed_date) 
      VALUES (new.date_key, new.time_key, new.account_key, new.reading_value, new.consumption, new.processed_date);

此规则不包含新列,因此始终为reading_id插入null。解决方案是将READ_id添加到DO INSTEAD的INSERT语句中。

答案 1 :(得分:1)

我无法重现它。请注意,在创建新列时,所有预先存在的行在该列中都将具有空值:

create table dw_readings(date_key date);
create table dw_readings_2012(
    check (extract(year from date_key) = 2012)
)   inherits(dw_readings);
;
insert into dw_readings_2012 (date_key) values ('2012-01-01'::date);
alter table dw_readings add column reading_id integer;
insert into dw_readings_2012 (date_key, reading_id) values ('2012-01-02'::date, 2);
select *
from dw_readings
;
  date_key  | reading_id 
------------+------------
 2012-01-01 |           
 2012-01-02 |          2
(2 rows)

答案 2 :(得分:0)

正如@xstrike所提到的,重新加载规则应该足够了。 例如,如果插入符号,则必须在每个分区上替换它:

CREATE OR REPLACE RULE table_partition_201608_rule
AS ON INSERT TO table_master WHERE date BETWEEN '2016-08-01 00:00:00.000' AND '2016-08-31 23:59:59.999'
DO INSTEAD (
  INSERT INTO table_partition_201608 VALUES (NEW.*)
);