1

问题在(尽管很长)标题中。我有这种方式的代码:

-- create the tables for models
CREATE TABLE invoice(
    id SERIAL PRIMARY KEY,
    value VARCHAR(8)
      CONSTRAINT valid_money CHECK(validate_invoice_money(value))
);

使用此程序:

CREATE OR REPLACE FUNCTION validate_invoice_money(test VARCHAR) RETURNS BOOLEAN AS $$
    import plpy
    import re

    if (re.match("^[0-9]+\\.[0-9]{2}$", test) == None):
        return False

    return True
$$ LANGUAGE plpython3u IMMUTABLE;

(这个例子的细节并不重要,我知道有比这更好的方法来验证一个值,比如使用MONEY类型。)

当尝试插入未通过此检查时,我收到以下错误:

ERROR  : new row for relation "invoice" violates check constraint "valid_model"
DETAIL : Failing row contains (1, "notvalid").

(错误/细节描述符是我自己的代码,但是 PostgreSQL 错误有一个错误并提供了一个细节字段。)

我有什么办法可以从我的 Python 程序中更改此错误的“详细信息”部分吗?

4

2 回答 2

2

在 Postgres 9.6+ 中,您可以使用实用程序函数从 plpython 函数中引发带有详细消息的错误,例如:

CREATE OR REPLACE FUNCTION validate_invoice_money(test VARCHAR) 
RETURNS BOOLEAN AS $$
    import re

    if (re.match("^[0-9]+\\.[0-9]{2}$", test) == None):
        plpy.error("custom exception message",
            detail="some info about exception",
            hint="hint for users")
        return False

    return True
$$ LANGUAGE plpython3u IMMUTABLE;

insert into invoice
values (default, 'notvalid');

ERROR:  plpy.Error: custom exception message
DETAIL:  some info about exception
HINT:  hint for users
CONTEXT:  Traceback (most recent call last):
  PL/Python function "validate_invoice_money", line 8, in <module>
    hint="hint for users")
PL/Python function "validate_invoice_money"
于 2017-12-26T00:25:55.433 回答
1

您不需要额外的语言;您可以对值约束使用普通的正则表达式:


-- create the tables for models
CREATE TABLE invoice(
    id SERIAL PRIMARY KEY,
    val VARCHAR(8)
      -- CONSTRAINT valid_money CHECK(validate_invoice_money(value))
      CONSTRAINT valid_money CHECK(val ~ '^[0-9]+\.[0-9]{2}$' )
);

INSERT INTO invoice (val) VALUES ('0123.98' ); -- success
INSERT INTO invoice (val) VALUES ('a123.98' ); -- failure

SELECT * FROM invoice;

结果:


CREATE TABLE
INSERT 0 1
ERROR:  new row for relation "invoice" violates check constraint "valid_money"
DETAIL:  Failing row contains (2, a123.98).
 id |   val   
----+---------
  1 | 0123.98
(1 row)

并回答这个问题:我认为您无法获得有关违反约束的其他信息。

于 2017-12-25T23:48:26.730 回答