В чем разница между "psql -c" и "psql -f" при выполнении нескольких запросов? - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь выполнить две команды sql (создать новую схему и таблицу) таким образом, чтобы можно было выполнить откат обеих команд в случае сбоя выполнения. База данных, к которой я подключаюсь, - это AWS Redshift.

create schema if not exists test_schema;
create table test_schema.test_table as select 1;

Первоначально я попытался выполнить эти команды программно с python, используя оба psycopg2 и pyodbc, и получил следующую ошибку:

ERROR:  schema "test_schema" does not exist

Я понял, что она не работает, потому что первая команда не выполняется, поэтому, чтобы исправить это, я попытался включить режим автоматической фиксации и обернуть операторы блоком "begin / end", что не помогло.

Когда я использовал psql CLI и запустил следующее, все работало как задумано (ошибки «схема не существует», и после отката исчезли и схема, и таблица):

dev=# begin;
BEGIN
dev=# create schema test_schema;
CREATE SCHEMA
dev=# create table test_schema.test_table as select 1;
SELECT
dev=# rollback;
ROLLBACK

Я попытался получить те же результаты, запустив в командной строке следующее:

psql -c "begin; create schema test_schema; create table test_schema.test_table as select 1;"

Это приводит к той же ошибке:

ERROR: schema "test_schema" does not exist

Однако, когда я поместил вышеуказанный код в файл и выполнил ту же команду, на этот раз с помощью -f это сработало:

psql -f create_schema_and_table.sql

Мои вопросы:

  1. В чем разница между выполнением запросов с помощью "psql -c" и "psql -f"?

  2. Как достичь того же результата программно, с помощью Python?

Большое спасибо!

1 Ответ

0 голосов
/ 16 января 2019

Я не знаю, что вы делаете неправильно, ваша команда "psql -c" работает отлично:

ads@diamond:~$ psql -c "begin; create schema test_schema; create table test_schema.test_table as select 1;" postgres
SELECT 1

psql отправит всю строку на сервер и выполнит ее за одну транзакцию. Ваша проблема в том, что вы начинаете транзакцию, используя «начало», но никогда не фиксируете ее. Поэтому в конце выполнения psql все ваши изменения будут отменены. Следующая команда psql не найдет ни схему, ни таблицу. Но пока все остается в одном вызове psql, последующие запросы в той же команде могут видеть вновь созданные объекты.

Вместо этого ваша строка запроса должна выглядеть следующим образом:

begin; create schema test_schema; create table test_schema.test_table as select 1; commit;

Или, более просто:

create schema test_schema; create table test_schema.test_table as select 1;

Оба будут работать.

...