sql >> Database >  >> RDS >> PostgreSQL

Converteer bytea naar dubbele precisie in PostgreSQL

Oké, ik heb een antwoord gevonden. In PostgreSQL kun je functies schrijven met Python. Om het gebruik van Python mogelijk te maken, moet u de specifieke versie van Python installeren die nodig is voor uw installatie van PostgreSQL en deze beschikbaar hebben in de omgevingsvariabele PATH. U kunt vinden welke versie van Python uw installatie van PostgreSQL nodig heeft door de installatie-opmerkingen te bekijken. Ik gebruik momenteel PostgreSQL 9.6.5 op Windows en het vraagt ​​om Python 3.3. Ik heb aanvankelijk de nieuwste Python 3.6 geprobeerd, maar het zou niet werken. Ik heb genoegen genomen met de nieuwste Python 3.3 voor Windows, namelijk 3.3.5.

Nadat je Python hebt geïnstalleerd, schakel je het in PostgreSQL in door CREATE EXTENSION plpython3u; uit te voeren. op uw database zoals hier gedocumenteerd https://www.postgresql.org/docs /current/static/plpython.html . Van daaruit kun je elke functie schrijven met Python-lichamen.

Voor mijn specifieke geval om te converteren van bytea tot double precision[] en terug schreef ik de volgende functies:

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

In mijn geval worden alle dubbels opgeslagen in little endian, dus ik gebruik < . Ik cache ook de import van de struct module in het globale woordenboek zoals beschreven in https://stackoverflow.com/a/15025425/5274457 . Ik heb GD gebruikt in plaats van SD omdat ik de import beschikbaar wil hebben in andere functies die ik kan schrijven. Voor informatie over GD en SD, zie https://www.postgresql .org/docs/current/static/plpython-sharing.html .

Om het in actie te zien wetende dat de blobs in mijn database zijn opgeslagen als little endian,

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

En het antwoord dat ik krijg is

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

waar 'efbeaddeefbeadde' is 'deadbeefdeadbeef' in little endian.




  1. Hoe een afbeelding in een mysql-database (tabel) in te voegen?

  2. Waarom dml-foutregistratie genegeerd in parallelle instructie

  3. Probleem met postgresql en pgadmin docker-containers

  4. Hoe de vermenigvuldigingswaarde in de while-lus in PHP berekenen?