sql >> Databáze >  >> RDS >> PostgreSQL

Chcete rychle převést z polí Python na PostgreSQL?

Nastavení

Chcete vytvořit spouštěče (opakovaně?) pomocí stejné spouštěcí funkce, jak je uvedeno v mé související odpovědi na dba.SE . Chcete-li vytvořit více, musíte do spouštěcí funkce předat hodnoty řádky s více hodnoty sloupců, tedy dvourozměrné pole. (Ale můžeme pracovat s jakýmkoli jasně definovaný řetězec!)

Jediný způsob, jak předat hodnoty spouštěcí funkci PL/pgSQL (jiné než hodnoty sloupců spouštěcího řádku), jsou text parametry, které jsou dostupné uvnitř funkce jako 0- založené pole textu ve speciální proměnné pole TG_ARGV[] . Můžete předat proměnný počet parametrů, ale dříve jsme diskutovali o jediném řetězcovém literálu představujícím vaše 2-dimenzionální pole.

Vstup pochází z 2rozměrného pole Pythonu s celým číslem se znaménkem čísla, která zapadají do Postgres typu integer . Použijte Postgres typ bigint pro pokrytí celých čísel bez znaménka as okomentoval .

Textová reprezentace v Pythonu vypadá takto:

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

Syntaxe literálu pole Postgres:

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

A chcete proces automatizovat.

Plná automatizace

Řetězec pro CREATE TRIGGER můžete zřetězit příkazu ve vašem klientovi nebo můžete zachovat logiku ve funkci na straně serveru a pouze předat parametry.

Ukázka příkladu funkce s názvem tabulky a řetězcem, který je předán spouštěcí funkci. Spouštěcí funkce insaft_function() je definováno ve vaší předchozí otázce na 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$;

Volejte:

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

Nebo:

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

db<>fiddle zde
Staré sqlfiddle

Nyní můžete předat buď [[1,2],[3,4]] (s hranatými závorkami) nebo {{1,2},{3,4}} (s kudrnatými závorkami). Oba fungují stejně. translate(_arg0, '[]', '{}' transformuje první do druhého tvaru.

Tato funkce zruší spouštěč se stejným názvem, pokud existuje, před vytvořením nového. Možná budete chtít vypustit nebo ponechat tento řádek:

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

Toto běží s oprávněními volající role DB. V případě potřeby byste jej mohli spustit s oprávněními superuživatele (nebo jinými). Viz:

Existuje mnoho způsobů, jak toho dosáhnout. Záleží na přesných požadavcích.

Vysvětlení format()

format() a datový typ regclass pomáhají bezpečně zřetězit příkaz DDL a znemožňují vkládání SQL. Viz:

Prvním argumentem je "formátovací řetězec" následovaný argumenty, které mají být vloženy do řetězce. Používám dolar-quoting , což pro příklad není nezbytně nutné, ale obecně je to dobrý nápad pro zřetězení dlouhých řetězců obsahujících jednoduché uvozovky:$$DROP TRIGGER ... $$

format() je modelován podle funkce C sprintf . %1$s je specifikátor formátu format() funkce. Znamená to, že první (1$ ) argument za formátovací řetězec je vložen jako řetězec bez uvozovek (%s ), odtud:%1$s . První argument pro formátování je _tbl v příkladu - regclass parametr je automaticky vykreslen jako právní identifikátor, v případě potřeby uvozen, takže format() nemusí dělat víc. Proto jen %s , nikoli %I (identifikátor). Podrobnosti naleznete v odkazované odpovědi výše.
Další používaný specifikátor formátu je %2$L :Druhý argument jako citovaný řetězcový literál .

Pokud s format() teprve začínáte , hrajte si s těmito jednoduchými příklady, abyste to pochopili:

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]', '[]', '{}'));

A přečtěte si příručku .




  1. Funkce Concat nefunguje - neplatný počet argumentů

  2. PostgreSQL v Helm:parametr initdbScripts

  3. Kontrola názvů databází a vytvoření databáze za běhu

  4. SQLAlchemy dychtivě načítá více vztahů