PostgreSQL явная проверка ненулевого нарушения происходит до ограничения проверки? - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь использовать именованные ограничения, чтобы иметь возможность определить, что и где именно произошло из сообщений об ошибках. Например, когда я устанавливаю ненулевое ограничение для столбца «foo» в таблице «bar», а затем пытаюсь добавить строку с нулевым значением, я получаю:

ERROR: null value in column "foo" violates not-null constraint

Я надеваю не получить имя таблицы, и я не могу использовать это сообщение об ошибке, чтобы извлечь любую полезную информацию. С другой стороны, когда я удаляю ограничение not-null и добавляю ограничение check (foo is not null), которое можно назвать как-то как bar__foo__nn, я сразу получаю имя таблицы, имя столбца и что-то вроде кода ошибки " nn "за ненулевое нарушение. Я даже могу проанализировать это имя ограничения, чтобы извлечь необходимую информацию для дальнейшей регистрации ошибок в моем приложении.

Из того, что я прочитал, явное ограничение "не ноль" должно быть более эффективным и позволить больше оптимизаций. Кроме того, первичные ключи должны иметь явное ограничение not-null. Поэтому я попытался использовать оба, но в результате я получаю только ошибку «по умолчанию», отличную от ненулевого нарушения, и не упомянул о моем «нестандартном» названном нарушении ограничения.

Есть ли способ использовать явное ненулевое ограничение и все же иметь некоторый удобный способ «настроить» потенциальную ошибку ненулевого нарушения?

РЕДАКТИРОВАТЬ

Я не упомянул, что я получить доступ к базе данных с помощью Python с помощью psycopg2. Я не хотел задавать этот psycopg2 c, поскольку я использую postgresql и в других средах, и общий обзор того, как это работает в postgresql, будет полезен. Например, как извлечь необходимую информацию (имя таблицы и имя столбца) внутри хранимой процедуры / функции, чтобы каким-то образом сериализовать ее в коде postgresql (в разделе исключений), чтобы приложение подключалось к база данных (будь то Python с psycopg2 или чем-то еще) видит ошибки так, как я хочу, чтобы они возникали при вызове хранимых процедур.

1 Ответ

1 голос
/ 02 апреля 2020

Вы отметили , поэтому я предполагаю, что вы заинтересованы в файле журнала PostgreSQL.

Если вы не установите log_min_error_statement в fatal или выше, оператор всегда будет быть включены в сообщение об ошибке:

2020-04-02 14:40:28.253 CEST [3414] ERROR:  null value in column "a1" violates not-null constraint
2020-04-02 14:40:28.253 CEST [3414] DETAIL:  Failing row contains (12, null).
2020-04-02 14:40:28.253 CEST [3414] STATEMENT:  INSERT INTO a VALUES (12, NULL);

Подсказка: , если вы используете log_destination = csvlog, файл журнала будет проще для анализа.

Если вы заинтересованы в сообщение, отправляемое клиенту, зависит от клиента или API, который вы используете для доступа к PostgreSQL. Сервер отправляет информацию вместе с сообщением об ошибке.

Вот как это работает с psql клиентом:

test=> \set VERBOSITY verbose
test=> INSERT INTO a VALUES (12, NULL);
ERROR:  23502: null value in column "a1" violates not-null constraint
DETAIL:  Failing row contains (12, null).
SCHEMA NAME:  laurenz
TABLE NAME:  a
COLUMN NAME:  a1
LOCATION:  ExecConstraints, execMain.c:1960

Поскольку вас интересует Python, вот Пример программы, выполняющей ту же инструкцию:

#!/usr/bin/python3

from psycopg2 import connect, Error
from psycopg2.extensions import quote_ident

conn = connect("dbname=test user=laurenz")

cur = conn.cursor()

try:
    cur.execute("INSERT INTO a VALUES (12, NULL)")
except Error as e:
    print("Error: {}".format(e.diag.message_primary))
    print("Detail: {}".format(e.diag.message_detail))
    print("SQLSTATE: {}".format(e.diag.sqlstate))
    print("Table: {}.{}".format(
               quote_ident(e.diag.schema_name, cur),
               quote_ident(e.diag.table_name, cur)
         ))

conn.commit()

cur.close()
conn.close()

Результат:

Error: null value in column "a1" violates not-null constraint
Detail: Failing row contains (12, null).
SQLSTATE: 23502
Table: "laurenz"."a"
...