PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Untuk mengkonversi dari array Python ke PostgreSQL dengan cepat?

Penyiapan

Anda ingin membuat pemicu (berulang kali?) menggunakan fungsi pemicu yang sama seperti yang dijelaskan dalam jawaban terkait saya di dba.SE . Anda harus meneruskan nilai ke fungsi pemicu untuk membuat banyak baris dengan banyak nilai kolom, maka array dua dimensi. (Tapi kita bisa bekerja dengan apa saja string yang jelas!)

Satu-satunya cara untuk meneruskan nilai ke fungsi pemicu PL/pgSQL (selain nilai kolom dari baris pemicu) adalah text parameter, yang dapat diakses di dalam fungsi sebagai 0- array berbasis teks dalam variabel array khusus TG_ARGV[] . Anda dapat melewatkan sejumlah variabel parameter, tetapi kita telah membahas literal string tunggal yang mewakili larik 2 dimensi Anda sebelumnya.

Input berasal dari larik Python 2 dimensi dengan integer bertanda angka, yang cocok dengan tipe Postgres integer . Gunakan jenis Postgres bigint untuk menutupi nomor integer yang tidak ditandatangani, sebagai dikomentari .

Representasi teks dalam Python terlihat seperti ini:

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

Sintaks untuk literal array Postgres:

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

Dan Anda ingin mengotomatiskan prosesnya.

Otomasi penuh

Anda dapat menggabungkan string untuk CREATE TRIGGER pernyataan di klien Anda atau Anda dapat mempertahankan logika dalam fungsi sisi server dan hanya meneruskan parameter.

Mendemonstrasikan fungsi contoh dengan mengambil nama tabel dan string yang diteruskan ke fungsi pemicu. Fungsi pemicu insaft_function() didefinisikan dalam pertanyaan Anda sebelumnya di 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$;

Telepon:

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

Atau:

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

db<>fiddle di sini
Lama sqlfiddle

Sekarang Anda dapat melewati [[1,2],[3,4]] (dengan tanda kurung siku) atau {{1,2},{3,4}} (dengan kurung kurawal). Keduanya bekerja sama. translate(_arg0, '[]', '{}' mengubah bentuk pertama menjadi bentuk kedua.

Fungsi ini menjatuhkan pemicu dengan nama yang sama jika ada, sebelum membuat yang baru. Anda mungkin ingin menghapus atau mempertahankan baris ini:

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

Ini berjalan dengan hak istimewa dari peran DB pemanggil. Anda dapat menjalankannya dengan hak pengguna super (atau lainnya) jika perlu. Lihat:

Ada banyak cara untuk mencapai ini. Itu tergantung pada persyaratan yang tepat.

Menjelaskan format()

format() dan tipe data regclass membantu untuk menggabungkan perintah DDL dengan aman dan membuat injeksi SQL menjadi tidak mungkin. Lihat:

Argumen pertama adalah "format string", diikuti oleh argumen yang akan disematkan dalam string. Saya menggunakan dollar-quoting , yang tidak sepenuhnya diperlukan untuk contoh, tetapi umumnya ide yang baik untuk menggabungkan string panjang yang berisi tanda kutip tunggal:$$DROP TRIGGER ... $$

format() dimodelkan di sepanjang fungsi C sprintf . %1$s adalah penentu format dari format format() fungsi. Artinya yang pertama (1$ ) argumen setelah string format dimasukkan sebagai string tanpa tanda kutip (%s ), maka:%1$s . Argumen pertama untuk memformat adalah _tbl dalam contoh - regclass parameter dirender sebagai pengenal hukum secara otomatis, tanda kutip ganda jika perlu, jadi format() tidak harus berbuat lebih banyak. Karenanya cukup %s , bukan %I (pengidentifikasi). Baca jawaban tertaut di atas untuk detailnya.
Penentu format lain yang digunakan adalah %2$L :Argumen kedua sebagai literal string yang dikutip .

Jika Anda baru mengenal format() , mainkan dengan contoh sederhana ini untuk memahami:

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

Dan baca manual .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JPA 2 @SequenceGenerator @GeneratedValue menghasilkan pelanggaran batasan unik

  2. Pembuatan objek Django dan Urutan Postgres

  3. Menerapkan Beberapa Fungsi Jendela Pada Partisi Yang Sama

  4. Bagaimana cara membuat daftar semua database dan skemanya di postgresql?

  5. Perulangan dalam kueri pemilihan