PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Konwersja bajtów na podwójną precyzję w PostgreSQL

Ok, znalazłem odpowiedź. W PostgreSQL możesz pisać funkcje za pomocą Pythona. Aby umożliwić korzystanie z Pythona, musisz zainstalować konkretną wersję Pythona wymaganą przez Twoją instalację PostgreSQL i udostępnić ją w zmiennej środowiskowej PATH. Możesz dowiedzieć się, jakiej wersji Pythona wymaga Twoja instalacja PostgreSQL, przeglądając uwagi dotyczące instalacji. Obecnie używam PostgreSQL 9.6.5 w systemie Windows i wywołuje Python 3.3. Początkowo próbowałem najnowszego Pythona 3.6, ale to nie zadziałało. Zdecydowałem się na najnowszy Python 3.3 dla Windows, czyli 3.3.5.

Po zainstalowaniu Pythona włączasz go w PostgreSQL, wykonując polecenie CREATE EXTENSION plpython3u; w Twojej bazie danych, jak udokumentowano tutaj https://www.postgresql.org/docs /current/static/plpython.html . Stamtąd możesz napisać dowolną funkcję z ciałami Pythona.

W moim konkretnym przypadku do konwersji z bytea do double precision[] iz powrotem napisałem następujące funkcje:

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$;

W moim przypadku wszystkie dublety są przechowywane w little endian, więc używam < . Buforuję również import struct w słowniku globalnym, jak opisano w https://stackoverflow.com/a/15025425/5274457 . Użyłem GD zamiast SD, ponieważ chcę, aby import był dostępny w innych funkcjach, które mogę napisać. Aby uzyskać informacje o GD i SD, zobacz https://www.postgresql .org/docs/current/static/plpython-sharing.html .

Aby zobaczyć to w akcji, wiedząc, że bloby w mojej bazie danych są przechowywane jako little endian,

SELECT bytea_to_double_array(decode('efbeaddeefbeadde', 'hex')), encode(double_array_to_bytea(array[-1.1885959257070704E148]), 'hex');

Odpowiedź, którą otrzymuję, to

bytea_to_double_array    | encode
double precision[]       | text
-------------------------+------------------
{-1.18859592570707e+148} | efbeaddeefbeadde

gdzie 'efbeaddeefbeadde' to 'deadbeefdeadbeef' w little endian.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. rake db:create baza wyrzutów nie istnieje błąd z postgresql

  2. HikariCP z PostgreSQL:setQueryTimeout(int) nie jest jeszcze zaimplementowany

  3. szyny dynamiczne, gdzie zapytanie sql

  4. Przekazywanie tablicy tablic jako parametru do funkcji

  5. Jak działa Z WYJĄTKIEM w PostgreSQL