sql >> Databasteknik >  >> RDS >> PostgreSQL

Konvertera bytea till dubbel precision i PostgreSQL

Okej, jag hittade ett svar. I PostgreSQL kan du skriva funktioner med Python. För att möjliggöra användningen av Python måste du installera den specifika version av Python som behövs för din installation av PostgreSQL och ha den tillgänglig i miljövariabeln PATH. Du kan hitta vilken version av Python din installation av PostgreSQL behöver genom att titta på installationsanteckningarna. Jag använder för närvarande PostgreSQL 9.6.5 på Windows och det kräver Python 3.3. Jag provade först den senaste Python 3.6, men det fungerade inte. Jag nöjde mig med den senaste Python 3.3 för Windows, vilket är 3.3.5.

Efter installation av Python aktiverar du det i PostgreSQL genom att köra CREATE EXTENSION plpython3u; på din databas som dokumenterats här https://www.postgresql.org/docs /current/static/plpython.html . Därifrån kan du skriva vilken funktion som helst med Python-kroppar.

För mitt specifika fall att konvertera från bytea till double precision[] och tillbaka skrev jag följande 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 mitt fall lagras alla dubblar i little endian, så jag använder < . Jag cachelagrar också importen av struct modul i den globala ordboken som beskrivs i https://stackoverflow.com/a/15025425/5274457 . Jag använde GD istället för SD eftersom jag vill ha importen tillgänglig i andra funktioner jag kan skriva. För information om GD och SD, se https://www.postgresql .org/docs/current/static/plpython-sharing.html .

För att se det i aktion med att veta att blobbarna i min databas lagras som little endian,

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

Och svaret jag får är

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

där 'efbeaddeefbeadde' är 'deadbeefdeadbeef' i little endian.




  1. Bästa sättet att hantera samtidighetsproblem

  2. Återställ automatisk inkrementräknare i postgres

  3. 12 MySQL/MariaDB Säkerhet Best Practices för Linux

  4. Hur man gör en rullande summa, varje rad måste inkludera summan av tidigare rader