PostgreSQL自动分区,StatementInvalid:PG :: NullValueNotAllowed

时间:2017-07-10 20:58:29

标签: ruby-on-rails postgresql activerecord

我试图从一组CSV文件中导入一个巨大的地址数据库。我按照tutorial自动创建postgres分区。

我用十八个字段创建我的数据库。每个字段都是varchar。 我想用于分区的字段是" comune"。

按照指南我创建了这个功能

CREATE OR REPLACE FUNCTION create_partition_and_insert() RETURNS trigger AS
  $BODY$
    DECLARE
      partition_comune TEXT;
      partition TEXT;
    BEGIN
      partition := TG_RELNAME || '_' || partition_comune;
      IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname=partition) THEN
        RAISE NOTICE 'A partition has been created %',partition;
        EXECUTE 'CREATE TABLE ' || partition || ' (check (comune = ''' || NEW.comune || ''')) INHERITS (' || TG_RELNAME || ');';
      END IF;
      EXECUTE 'INSERT INTO ' || partition || ' SELECT(' || TG_RELNAME || ' ' || quote_literal(NEW) || ').* RETURNING patent_id;';
      RETURN NULL;
    END;
  $BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

然后

CREATE TRIGGER address_list_insert_trigger
BEFORE INSERT ON address_list
FOR EACH ROW EXECUTE PROCEDURE create_partition_and_insert();

现在我尝试用Activerecord填充我的数据库。

a = AddressList.new hash
=> #<AddressList id_egon: "380100018695509", regione: "VALLE D'AOSTA", provincia: "AOSTA", comune: "AOSTA", frazione: "", procom_2016: "007003", ist_sez: "0000179", ist_pro: "007", ist_com: "003", dug: "REGIONE", via: "SARAILLON", presso: "", colore: "", num_civ: "34", esponente: "", civ_extraurb: "", liv_serv100_30: " 30", linea_lunga: "s">
irb(main):040:0> a.save
   (0.3ms)  BEGIN
  SQL (7.0ms)  INSERT INTO "address_list" ("id_egon", "regione", "provincia", "comune", "frazione", "procom_2016", "ist_sez", "ist_pro", "ist_com", "dug", "via", "presso", "colore", "num_civ", "esponente", "civ_extraurb", "liv_serv100_30", "linea_lunga") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)  [["id_egon", "380100018695509"], ["regione", "VALLE D'AOSTA"], ["provincia", "AOSTA"], ["comune", "AOSTA"], ["frazione", ""], ["procom_2016", "007003"], ["ist_sez", "0000179"], ["ist_pro", "007"], ["ist_com", "003"], ["dug", "REGIONE"], ["via", "SARAILLON"], ["presso", ""], ["colore", ""], ["num_civ", "34"], ["esponente", ""], ["civ_extraurb", ""], ["liv_serv100_30", " 30"], ["linea_lunga", "s"]]
   (0.3ms)  ROLLBACK
ActiveRecord::StatementInvalid: PG::NullValueNotAllowed: ERROR:  query string argument of EXECUTE is null
CONTEXT:  PL/pgSQL function create_partition_and_insert() line 9 at EXECUTE
: INSERT INTO "address_list" ("id_egon", "regione", "provincia", "comune", "frazione", "procom_2016", "ist_sez", "ist_pro", "ist_com", "dug", "via", "presso", "colore", "num_civ", "esponente", "civ_extraurb", "liv_serv100_30", "linea_lunga") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
    from (irb):40

我无法理解我的错误在哪里。有些值当然是空的

2 个答案:

答案 0 :(得分:0)

在函数中用于构建EXECUTE的变量之一中有一个null。

如果partitionNEW.comuneTG_RELNAME中的任何一个为空,则将它们连接到您的字符串将为null。这正是错误信息所说的内容。

您似乎无法设置partition_comune中使用的partition,因此很可能是您的空来源。

记住NULL意味着&#34;未知&#34;什么+未知显然是未知的。同样x <未知=未知和未知=未知未知。

答案 1 :(得分:0)

假设您需要分区,因为数据/索引不适合内存。

表格的结构是什么 \ d address_list?

有一个列定义为非null

OR

确保&#34; VALLE D&#39; AOSTA&#34;

有一个转义条款

&#34;用于postgres(指定区分大小写)列名,

&#39;用于封闭字符串。