Korma和Postgresql的默认ID?

时间:2016-03-09 22:45:58

标签: postgresql clojure compojure korma

我有以下架构:

CREATE TABLE IF NOT EXISTS art_pieces
(
  -- Art Data
  ID SERIAL PRIMARY KEY,
  title TEXT NOT NULL,
  description TEXT,
  price INT NULL,

  -- Relations
  artists_id INT NULL

);

--;;

CREATE TABLE IF NOT EXISTS artists
(
  -- Art Data
  ID SERIAL PRIMARY KEY,
  name TEXT NOT NULL
);

这是相应的艺术品实体:

(defentity art-pieces
  (table :art_pieces)
  (entity-fields
    :id
    :title
    :description
    :price
    :artists_id)
  (belongs-to artists))

我想知道为什么以下内容会返回PSQLException ERROR: null value in column "id" violates not-null constraint

(create-piece {:title "The Silence of the Lambda" 
               :description "Something something java beans and a nice chianti" 
               :price 5000})

ID SERIAL PRIMARY KEY字段不应自动填充吗?这与Korma与PSQL的互动有关吗?

1 个答案:

答案 0 :(得分:1)

INSERT INTO "art_pieces" ("description", "id", "price", "title") VALUES (?, NULL, ?, ?)

此处的问题是您尝试将NULL值插入id列。只有在省略列或使用DEFAULT关键字(而不是NULL)时才会插入默认值。

  

要将序列的下一个值插入到串行列中,请指定应为串行列分配其默认值。这可以通过从INSERT语句中的列列表中排除列,或通过使用DEFAULT关键字

来完成。

PostgreSQL Serial Types

因此您必须将查询更改为:

INSERT INTO "art_pieces" ("description", "id", "price", "title") VALUES (?, DEFAULT, ?, ?)
-- or
INSERT INTO "art_pieces" ("description", "price", "title") VALUES (?, ?, ?)

另一种解决方法(如果您无权更改查询)将添加trigger函数,该函数将自动替换NULL列中的id值:

CREATE OR REPLACE FUNCTION tf_art_pieces_bi() RETURNS trigger AS
$BODY$
BEGIN
    -- if insert NULL value into "id" column
    IF TG_OP = 'INSERT' AND new.id IS NULL THEN
        -- set "id" to the next sequence value
        new.id = nextval('art_pieces_id_seq');
    END IF;
    RETURN new; 
END;
$BODY$
LANGUAGE plpgsql;

CREATE TRIGGER art_pieces_bi
BEFORE INSERT
ON art_pieces
FOR EACH ROW EXECUTE PROCEDURE tf_art_pieces_bi();