Ok, tôi đã tìm thấy câu trả lời. Trong PostgreSQL, bạn có thể viết các hàm bằng Python. Để cho phép sử dụng Python, bạn phải cài đặt phiên bản Python cụ thể cần thiết khi cài đặt PostgreSQL của bạn và có sẵn phiên bản này trong biến môi trường PATH. Bạn có thể tìm thấy phiên bản Python nào mà quá trình cài đặt PostgreSQL của bạn cần bằng cách xem các ghi chú cài đặt. Tôi hiện đang sử dụng PostgreSQL 9.6.5 trên Windows và nó gọi Python 3.3. Ban đầu tôi đã thử Python 3.6 mới nhất, nhưng nó không hoạt động. Tôi đã giải quyết bằng Python 3.3 mới nhất dành cho Windows, là 3.3.5.
Sau khi cài đặt Python, bạn kích hoạt nó trong PostgreSQL bằng cách thực thi CREATE EXTENSION plpython3u;
trên cơ sở dữ liệu của bạn như được ghi lại tại đây https://www.postgresql.org/docs /current/static/plpython.html
. Từ đó, bạn có thể viết bất kỳ hàm nào với các phần thân Python.
Đối với trường hợp cụ thể của tôi để chuyển đổi từ bytea
thành double precision[]
và quay lại, tôi đã viết các hàm sau:
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$;
Trong trường hợp của tôi, tất cả các bộ đôi được lưu trữ trong ít endian, vì vậy tôi sử dụng <
. Tôi cũng lưu vào bộ nhớ cache việc nhập struct
mô-đun trong từ điển chung như được mô tả trong https://stackoverflow.com/a/15025425/5274457 . Tôi đã sử dụng GD thay vì SD vì tôi muốn nhập có sẵn trong các chức năng khác mà tôi có thể viết. Để biết thông tin về GD và SD, hãy xem https://www.postgresql .org / docs / current / static / plpython-sharing.html
.
Để xem nó hoạt động khi biết các đốm màu trong cơ sở dữ liệu của tôi được lưu trữ dưới dạng endian nhỏ,
SELECT bytea_to_double_array(decode('efbeaddeefbeadde', 'hex')), encode(double_array_to_bytea(array[-1.1885959257070704E148]), 'hex');
Và câu trả lời tôi nhận được là
bytea_to_double_array | encode
double precision[] | text
-------------------------+------------------
{-1.18859592570707e+148} | efbeaddeefbeadde
ở đâu 'efbeaddeefbeadde'
là 'deadbeefdeadbeef'
trong endian nhỏ.