PSQL (postgres или redshift) хранимая переменная для запроса и записи запроса в динамическое имя файла - PullRequest
0 голосов
/ 21 февраля 2019

Мой рабочий процесс adhoc часто приводит меня к клиенту psql, так часто, что я определяю полезные запросы или изменения настроек в моем файле .psqlrc.Я делюсь решением этой проблемы, потому что в Интернете есть несколько примеров, и поскольку вы не можете использовать перевод строки в метакоманде, синтаксис становится уродливым, а отладка занимает много времени.

Определение мета-команды psqlв переменной, которая запрашивает путь к файлу sql и записывает в локальный файл с динамическим именем файла

  • приглашение для файла sql выполнить
  • запрос на префикс выходного имени файла
  • создать динамическое имя выходного файла на основе отчетной недели ISO

Вот ручной пример шагов, которые я хочу обернуть в .pqslrc -определенную переменную:

-- the following at psql prompt =>>

select 'file_prefix' || '_week_'
  || to_char(next_day(current_date - 1 - 7 * 1, 'sat') + 1,'iyyy-iw') 
  || '.txt'  report_filename;
┌──────────────────────────────┐
│       report_filename        │
├──────────────────────────────┤
│ file_prefix_week_2019-07.txt │
└──────────────────────────────┘

\out file_prefix_week_2019-07.txt

\a \pset footer off   -- no border or row count to output file

\i 'path/to/sql_file.sql'
-- now I have a text file of the output locally on my machine

\out \a \pset footer on

=>>
-- back to normal terminal output

1 Ответ

0 голосов
/ 21 февраля 2019

Вот рабочее решение, которое может быть введено в командной строке psql или добавлено к .psqlrc и вызвано из командной строки psql с именем переменной:

-- newlines are included for readability but:
-- **remove all newlines when pasting to .psqlrc**

\set report '\\echo enter filename prefix:\\\\ \\prompt file_prefix \\\\
 \\echo enter sql file path:\\\\ \\prompt sql_file \\\\
 select :''file_prefix'' || ''_week_''
 || to_char(next_day(current_date - 1 - 7 * 1, ''sat'') + 1,''iyyy-iw'')
 || ''.txt''  report_filename \\gset \\\\
 \\pset footer off \\pset border 0 \\pset expanded off \\pset format unaligned \\\\
 \\out :report_filename \\\\
 \\i :sql_file \\\\ 
 \\out \\\\
 \\pset footer on  \\pset border 2 \\pset expanded auto
 \\pset format aligned \\pset linestyle unicode'

ключевые точки:

Postgres psql документация текущая версия

  • при копировании / вставке удалить всесимволы новой строки
  • переменная строка не может иметь символов новой строки, только одна длинная строка
  • строка содержится в одинарных кавычках '
  • символ \\ отделяетсякоманды
    • символ \ экранируется путем удвоения
    • , поэтому используйте \\ для \, \\\\ для \\
  • одиночные кавычки внутри строки экранируются путем удвоения
    • , поэтому используйте '' для ' внутри строки
    • это считается для :variables, которые также являются строками
  • \gset присваивает вывод запроса переменной имени столбца
  • , :sql_file может включать в себя spaКроме того, переменная сохраняется в виде текстовой строки, которую \i может анализировать без переноса как :''sql_file''

соответствующих компонентов в .psqlrc

-- .psqlrc
-- remove newlines from \set variable strings before pasting

\pset fieldsep '\t'
\set prompt_1 '%R%#> '
\set PROMPT1 :prompt_1

\set prompt_copyout 'copyout : : : copyout\n%R%#> '

-- helper variables
-- usage:
-- :copyout desired_output_filename
\set copyout '\\pset footer off \\pset border 0 \\pset expanded off
 \\pset format unaligned \\pset title \\pset null '''' 
 \\set PROMPT1 :prompt_copyout \\out '

-- usage to return to normal terminal output
-- :copyoff
\set copyoff '\\pset footer on  \\pset border 2 \\pset expanded auto
 \\pset format aligned \\pset title \\pset null ''[null]'' 
 \\set PROMPT1 :prompt_1 \\pset linestyle unicode \\out \\\\'

, переформулированных свспомогательные переменные

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

-- again remove all newlines before pasting into .psqlrc
\set report '\\echo enter filename prefix:\\\\ \\prompt file_prefix \\\\
 \\echo enter sql file path:\\\\ \\prompt sql_file \\\\
 select :''file_prefix'' || ''_week_''
 || to_char(next_day(current_date - 1 - 7 * 1, ''sat'') + 1,''iyyy-iw'')
 || ''.txt''  report_filename \\gset \\\\
 :copyout :report_filename \\\\
 \\i :sql_file \\\\ 
 :copyoff'
...