Oke, saya menemukan jawaban. Di PostgreSQL, Anda dapat menulis fungsi menggunakan Python. Untuk mengaktifkan penggunaan Python, Anda harus menginstal versi spesifik Python yang dibutuhkan oleh instalasi PostgreSQL Anda dan menyediakannya di variabel lingkungan PATH. Anda dapat menemukan versi Python mana yang dibutuhkan instalasi PostgreSQL Anda dengan melihat catatan instalasi. Saat ini saya menggunakan PostgreSQL 9.6.5 di Windows dan membutuhkan Python 3.3. Saya awalnya mencoba Python 3.6 terbaru, tetapi tidak berhasil. Saya memilih Python 3.3 terbaru untuk Windows, yaitu 3.3.5.
Setelah menginstal Python, Anda mengaktifkannya di PostgreSQL dengan menjalankan CREATE EXTENSION plpython3u;
pada database Anda seperti yang didokumentasikan di sini https://www.postgresql.org/docs /current/static/plpython.html
. Dari sana, Anda dapat menulis fungsi apa pun dengan badan Python.
Untuk kasus khusus saya untuk mengonversi dari bytea
untuk double precision[]
dan kembali, saya menulis fungsi berikut:
CREATE FUNCTION bytea_to_double_array(b bytea)
RETURNS double precision[]
LANGUAGE 'plpython3u'
AS $BODY$
if 'struct' in GD:
struct = GD['struct']
else:
import struct
GD['struct'] = struct
return struct.unpack('<' + str(int(len(b) / 8)) + 'd', b)
$BODY$;
CREATE FUNCTION double_array_to_bytea(dblarray double precision[])
RETURNS bytea
LANGUAGE 'plpython3u'
AS $BODY$
if 'struct' in GD:
struct = GD['struct']
else:
import struct
GD['struct'] = struct
# dblarray here is really a list.
# PostgreSQL passes SQL arrays as Python lists
return struct.pack('<' + str(int(len(dblarray))) + 'd', *dblarray)
$BODY$;
Dalam kasus saya, semua ganda disimpan di little endian, jadi saya menggunakan <
. Saya juga meng-cache impor struct
modul dalam kamus global seperti yang dijelaskan dalam https://stackoverflow.com/a/15025425/5274457 . Saya menggunakan GD daripada SD karena saya ingin impor tersedia di fungsi lain yang mungkin saya tulis. Untuk informasi tentang GD dan SD, lihat https://www.postgresql .org/docs/current/static/plpython-sharing.html
.
Untuk melihatnya beraksi mengetahui gumpalan di database saya disimpan sebagai little endian,
SELECT bytea_to_double_array(decode('efbeaddeefbeadde', 'hex')), encode(double_array_to_bytea(array[-1.1885959257070704E148]), 'hex');
Dan jawaban yang saya dapatkan adalah
bytea_to_double_array | encode
double precision[] | text
-------------------------+------------------
{-1.18859592570707e+148} | efbeaddeefbeadde
di mana 'efbeaddeefbeadde'
adalah 'deadbeefdeadbeef'
di little endian.