PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

За да конвертирате бързо от Python масиви в PostgreSQL?

Настройка

Искате да създавате задействания (многократно?), като използвате същата функция за задействане, както е посочено в моя свързан отговор на dba.SE . Трябва да подадете стойности към тригерната функция, за да създадете множество редове с множество стойности на колони, оттук и двумерният масив. (Но можем да работим с всеки ясно дефиниран низ!)

Единственият начин за предаване на стойности към функция за задействане на PL/pgSQL (различен от стойностите на колона на задействащия ред) е текст параметри, които са достъпни във функцията като 0- базиран масив от текст в специалната променлива на масива TG_ARGV[] . Можете да подадете променлив брой параметри, но по-рано обсъдихме един низов литерал, представляващ вашия двуизмерен масив.

Входът идва от двумерен масив на Python с цело число със знак числа, които се вписват в типа integer на Postgres . Използвайте Postgres тип bigint за покриване на цели числа без знак, като коментира .

Текстовото представяне в Python изглежда така:

[[1,2],[3,4]]

Синтаксис за литерал на масив на Postgres:

{{1,2},{3,4}}

И искате да автоматизирате процеса.

Пълна автоматизация

Можете да свържете низа за CREATE TRIGGER оператор във вашия клиент или можете да запазите логиката във функция от страна на сървъра и просто да подадете параметри.

Демонстриране на примерна функция, която взема име на таблица и низ, който е предаден на тригерната функция. Задействащата функция insaft_function() е дефиниран в предишния ви въпрос на dba.SE .

CREATE OR REPLACE FUNCTION f_create_my_trigger(_tbl regclass, _arg0 text)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   EXECUTE format($$
      DROP TRIGGER IF EXISTS insaft_%1$s_ids ON %1$s;
      CREATE TRIGGER insaft_%1$s_ids
      AFTER INSERT ON %1$s
      FOR EACH ROW EXECUTE PROCEDURE insaft_function(%2$L)$$
                , _tbl
                , translate(_arg0, '[]', '{}')
      );
END 
$func$;

Обаждане:

SELECT f_create_my_trigger('measurements', '[[1,2],[3,4]]');

Или:

SELECT f_create_my_trigger('some_other_table', '{{5,6},{7,8}}');

db<>fiddle тук
Стар sqlfiddle

Сега можете да подадете или [[1,2],[3,4]] (с квадратни скоби) или {{1,2},{3,4}} (с фигурни скоби). И двете работят еднакво. translate(_arg0, '[]', '{}' трансформира първата във втора форма.

Тази функция премахва тригер със същото име, ако съществува, преди да създаде новия. Може да искате да премахнете или запазите този ред:

DROP TRIGGER IF EXISTS insaft_%1$s_ids ON %1$s;

Това се изпълнява с привилегиите на извикващата DB роля. Можете да го накарате да работи с привилегии на суперпотребител (или други), ако е необходимо. Вижте:

Има много начини да постигнете това. Зависи от точните изисквания.

Обяснение на format()

format() и типът данни regclass помагат за безопасното свързване на DDL командата и правят невъзможно SQL инжектирането. Вижте:

Първият аргумент е "форматният низ", следван от аргументите, които трябва да бъдат вградени в низа. Използвам долар-котиране , което не е строго необходимо за примера, но като цяло е добра идея за свързване на дълги низове, съдържащи единични кавички:$$DROP TRIGGER ... $$

format() се моделира по C функцията sprintf . %1$s е спецификатор на формат на формат( ) функция. Това означава, че първият (1$ ) аргумент след форматиращия низ се вмъква като низ без кавички (%s ), следователно:%1$s . Първият аргумент за форматиране е _tbl в примера - regclass параметърът се изобразява като легален идентификатор автоматично, в двойни кавички, ако е необходимо, така че format() не трябва да прави повече. Следователно само %s , а не %I (идентификатор). Прочетете свързания отговор по-горе за подробности.
Другият използван спецификатор на формат е %2$L :Втори аргумент като цитиран низов литерал .

Ако не сте запознати с format() , поиграйте с тези прости примери, за да разберете:

SELECT format('input -->|%s|<-- here', '[1,2]')
     , format('input -->|%s|<-- here', translate('[1,2]', '[]', '{}'))
     , format('input -->|%L|<-- here', translate('[1,2]', '[]', '{}'))
     , format('input -->|%I|<-- here', translate('[1,2]', '[]', '{}'));

И прочетете ръководството .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как мога да съхранявам HTML код в поле на таблица на Postgresql DB?

  2. Възможно ли е да се предаде рекурсор като параметър директно на FETCH на Npgsql?

  3. Какъв е правилният начин за използване на модула node.js postgresql?

  4. Добавянето на колона като външен ключ дава ГРЕШКА колона, посочена в ограничението за външен ключ, не съществува

  5. Актуализирайте таблица и покажете актуализирани редове с една SQL команда