sql >> Database teknologi >  >> RDS >> PostgreSQL

Konverter bytea til dobbelt præcision i PostgreSQL

Ok, jeg fandt et svar. I PostgreSQL kan du skrive funktioner ved hjælp af Python. For at aktivere brugen af ​​Python, skal du installere den specifikke version af Python, der er nødvendig for din installation af PostgreSQL, og have den tilgængelig i PATH-miljøvariablen. Du kan finde ud af, hvilken version af Python din installation af PostgreSQL har brug for, ved at se på installationsnoterne. Jeg bruger i øjeblikket PostgreSQL 9.6.5 på Windows, og det kræver Python 3.3. Jeg prøvede i første omgang den nyeste Python 3.6, men det virkede ikke. Jeg nøjedes med den seneste Python 3.3 til Windows, som er 3.3.5.

Efter installation af Python, aktiverer du det i PostgreSQL ved at udføre CREATE EXTENSION plpython3u; på din database som dokumenteret her https://www.postgresql.org/docs /current/static/plpython.html . Derfra kan du skrive enhver funktion med Python-kroppe.

For mit specifikke tilfælde at konvertere fra bytea til double precision[] og tilbage skrev jeg følgende funktioner:

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

I mit tilfælde er alle doublerne gemt i little endian, så jeg bruger < . Jeg cacher også importen af ​​struct modul i den globale ordbog som beskrevet i https://stackoverflow.com/a/15025425/5274457 . Jeg brugte GD i stedet for SD, fordi jeg vil have importen tilgængelig i andre funktioner, jeg kan skrive. For information om GD og SD, se https://www.postgresql .org/docs/current/static/plpython-sharing.html .

For at se det i aktion vel vidende, at klatterne i min database er gemt som little endian,

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

Og det svar jeg får er

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

hvor 'efbeaddeefbeadde' er 'deadbeefdeadbeef' i lille endian.




  1. Få optælling fra 2 bord og gruppe efter måned

  2. mysql REPLACE-forespørgsel med flere primære nøgler

  3. Pil notation

  4. TEMPFILE Offline fysisk standby