web-dev-qa-db-fra.com

Générer un UUID dans Postgres pour une instruction Insert?

Ma question est plutôt simple. Je connais le concept d'un UUID et je souhaite en générer un pour faire référence à chaque "élément" d'un "magasin" dans ma base de données avec. Semble raisonnable non?

Le problème est que la ligne suivante renvoie une erreur:

honeydb=# insert into items values(
uuid_generate_v4(), 54.321, 31, 'desc 1', 31.94);
ERROR:  function uuid_generate_v4() does not exist
LINE 2: uuid_generate_v4(), 54.321, 31, 'desc 1', 31.94);
        ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

J'ai lu la page à l'adresse suivante: http://www.postgresql.org/docs/current/static/uuid-ossp.html

enter image description here

J'utilise Postgres 8.4 sur Ubuntu 10.04 x64.

293
anon58192932

_uuid-ossp_ est un module contrib, il n'est donc pas chargé sur le serveur par défaut. Vous devez le charger dans votre base de données pour l'utiliser.

Pour les versions modernes de PostgreSQL (9.1 et plus récentes), rien de plus simple:

_CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
_

mais pour les versions 9.0 et inférieures, vous devez exécuter le script SQL pour charger l'extension. Voir la documentation pour les modules contrib en 8.4 .

Pour la page 9.1 et les versions plus récentes, indiquez plutôt les documents de contribution actuels et CREATE EXTENSION . Ces fonctionnalités n'existent pas dans les versions 9.0 ou antérieures, comme votre version 8.4.

Si vous utilisez une version empaquetée de PostgreSQL, vous devrez peut-être installer un paquet séparé contenant les modules contrib et les extensions. Recherchez dans votre base de données de gestionnaire de paquets "postgres" et "contrib".

372
Craig Ringer

Sans extensions (triche)

SELECT uuid_in(md5(random()::text || clock_timestamp()::text)::cstring);

output>> c2d29867-3d0b-d497-9191-18a9d8ee7830

(fonctionne au moins en 8.4)

  • Merci à @Erwin Brandstetter pour ses explications sur clock_timestamp().

Si vous avez besoin d'un UUID v4 valide

SELECT uuid_in(overlay(overlay(md5(random()::text || ':' || clock_timestamp()::text) placing '4' from 13) placing to_hex(floor(random()*(11-8+1) + 8)::int)::text from 17)::cstring);

enter image description here * Merci à @ Denis Stafichuk @ Karsten et @ autronix


De plus, dans Postgres moderne, vous pouvez simplement lancer:

SELECT md5(random()::text || clock_timestamp()::text)::uuid

234
ZuzEL

Le réponse de Craig Ringer est correct. Voici un peu plus d'informations sur Postgres 9.1 et les versions ultérieures…

L'extension est-elle disponible?

Vous ne pouvez installer une extension que si elle a déjà été construite pour votre installation Postgres (votre cluster dans PostgreSQL). Par exemple, j'ai trouvé l'extension id-ossp incluse dans le programme d'installation de Mac OS X gentiment fournie par EnterpriseDB.com. N'importe lequel des quelques dizaines d'extensions peut être disponible.

Pour voir si l'extension uuid-ossp est disponible dans votre cluster Postgres, exécutez ce SQL pour interroger le catalogue système pg_available_extensions :

_SELECT * FROM pg_available_extensions;
_

Installer une extension

Pour installer cette extension liée à UUID , utilisez la commande CREATE EXTENSION comme indiqué dans ce SQL:

_CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
_

Attention: J'ai trouvé les caractères de marque de guillemet entourant le nom du poste requis, malgré la documentation contraire.

Le comité de normalisation SQL ou l'équipe Postgres ont choisi un nom étrange pour cette commande. À mon avis, ils auraient dû choisir quelque chose comme "INSTALLER UNE EXTENSION" ou "UTILISER UNE EXTENSION".

Vérifier l'installation

Vous pouvez vérifier que l'extension a bien été installée dans la base de données souhaitée en exécutant ce SQL pour interroger le catalogue système pg_extension :

_SELECT * FROM pg_extension;
_

UUID comme valeur par défaut

Pour plus d'informations, voir la question: valeur par défaut de la colonne UUID dans Postgres

L'ancienne manière

Les informations ci-dessus utilisent la nouvelle fonctionnalité Extensions ajoutée à Postgres 9.1. Dans les versions précédentes, nous devions trouver et exécuter un script dans un fichier . Sql . La fonctionnalité Extensions a été ajoutée pour faciliter l’installation, nécessitant un peu plus de travail pour le créateur d’une extension pour moins de travail de la part de l’utilisateur/consommateur de l’extension. Voir mon blog post pour plus de discussion.

Types d'UUID

À propos, le code de la question appelle la fonction uuid_generate_v4(). Cela génère un type appelé Version 4 où presque tous les 128 bits sont générés aléatoirement. Bien que cela soit correct pour une utilisation limitée sur un plus petit ensemble de lignes, si vous souhaitez éliminer virtuellement toute possibilité de collision, utilisez une autre "version" de l'UUID.

Par exemple, l'original Version 1 combine le adresse MAC de l'ordinateur hôte avec la date/heure actuelle et un nombre arbitraire, le risque de collision est pratiquement nul.

Pour plus de discussion, voir ma réponse sur la question connexe.

66
Basil Bourque

pgcrypto Extension

Depuis Postgres 9.4, le module pgcrypto inclut la fonction gen_random_uuid() . Cette fonction génère l'un des nombres aléatoires type d'UUID de version 4 .

Obtenez des modules de contribution, s'ils ne sont pas déjà disponibles.

Sudo apt-get install postgresql-contrib-9.4

Utilisez le module pgcrypto.

CREATE EXTENSION "pgcrypto";

La fonction gen_random_uuid() devrait maintenant être disponible;

Exemple d'utilisation.

INSERT INTO items VALUES( gen_random_uuid(), 54.321, 31, 'desc 1', 31.94 ) ;


Citation de doc Postgres sur uuid-ossp module.

Remarque: Si vous avez uniquement besoin d'UUID générés aléatoirement (version 4), envisagez plutôt d'utiliser la fonction gen_random_uuid () du module pgcrypto.

55
brillout
ALTER TABLE table_name ALTER COLUMN id SET DEFAULT uuid_in((md5((random())::text))::cstring);

Après avoir lu la réponse de @ ZuzEL, j'ai utilisé le code ci-dessus comme valeur par défaut de l'identifiant de colonne et tout fonctionne correctement.

1
Paolo Fernandes