Generare UUID v4 in Python — Guida uuid.uuid4()
Usa il Generatore UUID v4 gratuito direttamente nel tuo browser — nessuna installazione.
Prova Generatore UUID v4 online →Ogni volta che ho bisogno di un identificatore resistente alle collisioni per una riga di database, una traccia API o un token di sessione, la risposta è generare UUID v4 in Python — una riga, zero dipendenze: uuid.uuid4(). Il modulo uuid integrato di Python usa os.urandom() per casualità crittograficamente sicura. Per un UUID rapido senza scrivere codice, il generatore UUID v4 online funziona all'istante. Questa guida tratta gli attributi dell'oggetto UUID, la generazione in blocco, la serializzazione JSON, l'archiviazione su database, la validazione, uuid-utils (~10× più veloce, implementato in Rust) e i quattro errori più comuni — tutto con Python 3.8+.
- →
uuid.uuid4()è integrato nella stdlib di Python — bastaimport uuid, nessun pip install necessario. - →Il valore restituito è un oggetto
uuid.UUID, non una stringa — usastr(),.hexo.bytesper scegliere la rappresentazione adatta al tuo livello di archiviazione. - →UUID v4 usa 122 bit casuali da
os.urandom()— crittograficamente sicuro, senza esposizione di indirizzi MAC o timestamp. - →Per servizi ad alta frequenza,
pip install uuid-utilsè un sostituto diretto ~10 volte più veloce, implementato in Rust. - →Non passare mai
uuid.uuid4(senza parentesi) come argomento predefinito direttamente in una dataclass o in un modello Pydantic — in quel caso tutte le istanze condividerebbero un singolo UUID.
Cos'è UUID v4?
Un UUID (Universally Unique Identifier) è un'etichetta a 128 bit formattata come 32 cifre esadecimali divise in cinque gruppi da trattini: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. La versione 4 è la variante più diffusa: 122 di quei 128 bit sono generati casualmente, e i restanti 6 bit codificano la versione (4) e la variante (RFC 4122). Non è presente nessun timestamp né identificatore dell'host — l'identificatore è completamente opaco e rispettoso della privacy. La probabilità che due UUID v4 generati indipendentemente collidano è talmente ridotta che nella pratica non accade mai, anche in sistemi distribuiti che generano milioni di ID al secondo.
event_id = "evt-" + str(random.randint(100000, 999999)) # fragile, not unique
event_id = str(uuid.uuid4()) # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e
uuid.uuid4() — Il modo standard per generare UUID v4 in Python
Il modulo uuid fa parte della libreria standard di Python. Chiamare uuid.uuid4() restituisce un oggetto uuid.UUID con un insieme completo di attributi per diverse rappresentazioni. La conversione in stringa con str() produce il formato con trattini canonico che API, database e header HTTP si aspettano.
import uuid # Genera un UUID v4 request_id = uuid.uuid4() print(request_id) # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e print(type(request_id)) # <class 'uuid.UUID'> print(request_id.version) # 4 # Converti in stringa per JSON / header HTTP print(str(request_id)) # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" print(request_id.hex) # "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (senza trattini) print(request_id.bytes) # b';...' (16 byte grezzi)
Un pattern comune nel mondo reale consiste nell'allegare un UUID a ogni richiesta API in uscita per poter correlare i log tra i servizi. Ecco un wrapper minimale per una sessione requests che inietta un UUID fresco in ogni chiamata:
import uuid
import requests
def call_api(endpoint: str, payload: dict) -> dict:
trace_id = str(uuid.uuid4())
headers = {
"X-Request-ID": trace_id,
"Content-Type": "application/json",
}
response = requests.post(endpoint, json=payload, headers=headers, timeout=10)
response.raise_for_status()
return {"trace_id": trace_id, "data": response.json()}
# result["trace_id"] permette di trovare la richiesta esatta in tutti i log del servizio
result = call_api("https://api.example.com/v1/orders", {"product_id": "prod_7x2k", "qty": 3})
print(result["trace_id"]) # es. "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e"Per generare UUID in blocco — ad esempio, pre-popolare un batch di righe nel database — una list comprehension è idiomatica e leggibile:
import uuid
# Pre-genera ID per 1000 eventi di telemetria
event_ids = [str(uuid.uuid4()) for _ in range(1000)]
print(f"Generated {len(event_ids)} unique IDs")
print(event_ids[0]) # es. "a1c2e3f4-..."
print(event_ids[-1]) # valore diverso ogni voltaHai bisogno di un UUID rapido senza eseguire codice? Usa il generatore UUID v4 online per copiare un valore fresco con un clic, o generane centinaia in blocco — utile per popolare database di test o file di fixture.
uuid.uuid4() chiama os.urandom(16) internamente, poi imposta i bit 6–7 del byte 8 a 10 (variante) e i bit 12–15 del byte 6 a 0100 (versione 4). I restanti 122 bit sono casuali. Ecco perché non puoi fidarti della versione a meno che non analizzi con uuid.UUID().Attributi e rappresentazioni dell'oggetto UUID
L'oggetto uuid.UUID espone più rappresentazioni dello stesso valore a 128 bit. Scegliere quella giusta per il proprio livello di archiviazione previene la corruzione silenziosa dei dati e lo spreco di byte.
import uuid
u = uuid.uuid4()
print(str(u)) # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" (36 caratteri)
print(u.hex) # "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (32 caratteri, senza trattini)
print(u.bytes) # b';...' (16 byte, big-endian)
print(u.bytes_le) # b'...' (16 byte, little-endian)
print(u.int) # 78823... (intero a 128 bit)
print(u.version) # 4
print(u.variant) # 'specified in RFC 4122'
# Round-trip: ricostruzione dalla stringa
reconstructed = uuid.UUID("3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e")
print(reconstructed == u) # True (se u aveva quel valore)Per PostgreSQL con psycopg2 o asyncpg, passa direttamente l'oggetto UUID — il driver gestisce la mappatura al tipo di colonna uuid nativo. Per SQLite, usa str(u) (TEXT) o u.bytes (BLOB, 16 byte contro 36 della stringa). Per efficienza di archiviazione su larga scala, .bytes è il 55% più piccolo rispetto alla stringa canonica.
Validazione e analisi di stringhe UUID v4 in Python
Ogni volta che un UUID arriva dall'input dell'utente, da un parametro di percorso URL o da un'API upstream, dovresti validarlo prima di usarlo come chiave di database. L'approccio idiomatico è tentare la costruzione con uuid.UUID() e intercettare ValueError. Puoi anche verificare che il valore in ingresso sia specificamente la versione 4 controllando .version.
import uuid
def parse_uuid4(raw: str) -> uuid.UUID:
"""
Analizza e valida una stringa UUID v4.
Solleva ValueError per formato non valido o versione errata.
"""
try:
u = uuid.UUID(raw)
except ValueError as exc:
raise ValueError(f"Invalid UUID format: {raw!r}") from exc
if u.version != 4:
raise ValueError(f"Expected UUID v4, got v{u.version}: {raw!r}")
return u
# Utilizzo in un handler di route FastAPI / Flask
def get_order(order_id: str):
try:
uid = parse_uuid4(order_id)
except ValueError as exc:
return {"error": str(exc)}, 400
# sicuro da usare uid in una query DB
return {"order_id": str(uid), "status": "processing"}uuid.UUID() accetta stringhe con o senza trattini, e accetta anche il prefisso urn:uuid:. Quindi "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (senza trattini) e "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" vengono entrambi analizzati nello stesso oggetto.UUID v4 in payload JSON e risposte API
Lo standard JSON non ha un tipo UUID — un UUID in JSON è sempre una stringa. Questo significa che devi convertire l'oggetto uuid.UUID in stringa prima di passarlo a json.dumps(). L'approccio più pulito è una sottoclasse personalizzata di JSONEncoder così non devi disseminare chiamate str() in tutto il tuo codebase.
import json
import uuid
from datetime import datetime
class ApiEncoder(json.JSONEncoder):
"""Serializza oggetti UUID e datetime nelle risposte JSON."""
def default(self, obj):
if isinstance(obj, uuid.UUID):
return str(obj)
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
# Risposta API realistica con UUID annidati
api_response = {
"request_id": uuid.uuid4(),
"created_at": datetime(2026, 3, 14, 9, 41, 0),
"order": {
"id": uuid.uuid4(),
"customer_id": uuid.uuid4(),
"items": [
{"product_id": uuid.uuid4(), "sku": "NVX-9000", "qty": 2},
],
},
}
print(json.dumps(api_response, indent=2, cls=ApiEncoder))
# {
# "request_id": "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e",
# "created_at": "2026-03-14T09:41:00",
# "order": {
# "id": "a1c2e3f4-...",
# ...
# }
# }Per una singola chiamata di serializzazione, il parametro default= è più semplice della sottoclasse:
import json, uuid
event_id = uuid.uuid4()
payload = {"event_id": event_id, "action": "checkout"}
# Passa un callable; chiamato solo per i tipi che json non sa gestire
json_str = json.dumps(payload, default=str)
print(json_str) # {"event_id": "3b1f8a9d-...", "action": "checkout"}Quando ricevi una risposta da un'API esterna, analizza le stringhe UUID e riconvertile in oggetti così il tuo codice ottiene il set completo di attributi e la type safety:
import json
import uuid
import requests
def fetch_shipment(shipment_id: str) -> dict:
"""Recupera una spedizione e restituisce con campi UUID tipizzati."""
response = requests.get(
f"https://api.logistics.example.com/v2/shipments/{shipment_id}",
headers={"Accept": "application/json"},
timeout=10,
)
response.raise_for_status()
data = response.json()
# Analizza i campi UUID e riconvertili in oggetti uuid.UUID
try:
data["id"] = uuid.UUID(data["id"])
data["carrier_id"] = uuid.UUID(data["carrier_id"])
except (KeyError, ValueError) as exc:
raise RuntimeError(f"Malformed shipment response: {exc}") from exc
return dataPer aggiornare i campi UUID in un file JSON su disco — ad esempio, ruotare un correlation ID in un file di configurazione o di seed — leggi, modifica e riscrivi atomicamente:
import json, uuid
def rotate_correlation_id(path: str) -> str:
"""Sostituisce o aggiunge 'correlation_id' in un file JSON. Restituisce il nuovo UUID."""
try:
with open(path) as f:
data = json.load(f)
except FileNotFoundError:
data = {}
except json.JSONDecodeError as exc:
raise ValueError(f"Invalid JSON in {path!r}: {exc}") from exc
new_id = str(uuid.uuid4())
data["correlation_id"] = new_id
with open(path, "w") as f:
json.dump(data, f, indent=2)
return new_idSe non vuoi eseguire uno script ogni volta che devi ispezionare un UUID da una risposta API, incollalo direttamente nell' UUID Decoder — mostra versione, variante e tutti i campi senza scrivere codice.
Genera UUID v4 dalla riga di comando con Python
Il modulo uuid di Python non espone un sottocomando CLI standalone come python -m json.tool, ma un one-liner copre lo stesso caso d'uso. Questi comandi sono utili negli script shell, nelle pipeline CI e ogni volta che hai bisogno di un identificatore temporaneo senza aprire un REPL.
# UUID v4 singolo python3 -c "import uuid; print(uuid.uuid4())" # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e # Formato hex senza trattini — utile per nomi di file e variabili d'ambiente python3 -c "import uuid; print(uuid.uuid4().hex)" # 3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e # Genera 5 UUID per uno script di seed batch python3 -c "import uuid; [print(uuid.uuid4()) for _ in range(5)]" # Usa in una variabile shell DEPLOY_ID=$(python3 -c "import uuid; print(uuid.uuid4())") echo "Deploying with ID: $DEPLOY_ID"
uuidgen (un'utility C) produce valori UUID v4 ed è più veloce per i puri script shell. Usa il one-liner Python quando sei già in un ambiente incentrato su Python e vuoi coerenza con il modo in cui gli UUID vengono generati nel codice della tua applicazione.UUID v4 ad alte prestazioni con uuid-utils
Il modulo uuid.uuid4() della libreria standard è abbastanza veloce per la maggior parte delle applicazioni — con pochi microsecondi per chiamata gestisce comodamente migliaia di ID al secondo. Se stai generando UUID nel percorso critico di un servizio ad alta frequenza (inserimenti in blocco, telemetria per evento su larga scala, o generazione di ID di richiesta sotto carico pesante), uuid-utils è un sostituto diretto implementato in Rust che nei benchmark raggiunge circa 10 volte la velocità della stdlib.
pip install uuid-utils
# uuid_utils è un sostituto diretto del modulo uuid della stdlib import uuid_utils as uuid # Stessa API della stdlib request_id = uuid.uuid4() print(request_id) # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e print(str(request_id)) # stringa canonica print(request_id.hex) # hex senza trattini print(request_id.version) # 4 # Supporta anche v7 (ordinato per tempo, ottimo come chiave primaria nei DB) time_ordered_id = uuid.uuid7() print(time_ordered_id) # inizia con il prefisso del timestamp corrente
isinstance(u, uuid.UUID) stretti dalla libreria standard, usa la modalità compat: import uuid_utils.compat as uuid. La modalità compat è leggermente più lenta di quella predefinita ma comunque più veloce della stdlib.UUID v4 nelle Dataclass e nei modelli Pydantic
Le dataclass di Python e i modelli Pydantic supportano entrambi i campi UUID in modo nativo. Il pattern fondamentale quando si usa UUID come default auto-generato è passare il riferimento alla funzione, non il risultato di una chiamata — altrimenti ogni istanza condivide lo stesso UUID.
from dataclasses import dataclass, field
import uuid
@dataclass
class WorkerJob:
job_id: uuid.UUID = field(default_factory=uuid.uuid4)
worker_id: str = "worker-01"
payload: dict = field(default_factory=dict)
job1 = WorkerJob(payload={"task": "resize_image", "src": "uploads/img_4932.png"})
job2 = WorkerJob(payload={"task": "send_email", "to": "ops@example.com"})
print(job1.job_id) # univoco per istanza
print(job2.job_id) # diverso da job1.job_id
print(job1.job_id == job2.job_id) # Falsefrom pydantic import BaseModel, Field
import uuid
class OrderEvent(BaseModel):
event_id: uuid.UUID = Field(default_factory=uuid.uuid4)
order_id: uuid.UUID
status: str
amount_cents: int
event = OrderEvent(
order_id=uuid.UUID("a1c2e3f4-5b6d-4e7f-8c9d-0a1b2c3d4e5f"),
status="payment_confirmed",
amount_cents=4995,
)
print(event.model_dump_json(indent=2))
# {
# "event_id": "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e",
# "order_id": "a1c2e3f4-5b6d-4e7f-8c9d-0a1b2c3d4e5f",
# "status": "payment_confirmed",
# "amount_cents": 4995
# }
# Pydantic v2 serializza uuid.UUID come stringa automaticamenteErrori comuni nella generazione di UUID v4 in Python
Ho visto tutti e quattro questi pattern apparire nelle code review e negli incidenti in produzione — sono facili da perdere perché non sollevano un errore immediatamente.
Problema: Passare uuid.uuid4 (l'oggetto funzione) come valore predefinito in una dataclass o modello senza avvolgerlo in default_factory — Python valuta il default una sola volta alla definizione della classe, quindi ogni istanza condivide lo stesso UUID.
Soluzione: Usa default_factory=uuid.uuid4 nelle dataclass o Field(default_factory=uuid.uuid4) in Pydantic così un UUID fresco viene generato per ogni istanza.
@dataclass
class Session:
# SBAGLIATO: valutato una volta, tutte le istanze condividono questo UUID
session_id: uuid.UUID = uuid.uuid4()@dataclass
class Session:
# CORRETTO: la factory viene chiamata per ogni istanza
session_id: uuid.UUID = field(default_factory=uuid.uuid4)Problema: Gli oggetti uuid.UUID non sono uguali alle stringhe semplici, quindi session_id == '3b1f8a9d-...' restituisce sempre False anche quando il valore corrisponde — rompendo silenziosamente le ricerche.
Soluzione: Confronta sempre UUID con UUID: avvolgi la stringa con uuid.UUID() prima di confrontare, oppure converti entrambi i lati in str().
# Restituisce False anche quando i valori corrispondono
if record["session_id"] == "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e":
revoke_session(record)target = uuid.UUID("3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e")
if record["session_id"] == target: # entrambi sono uuid.UUID
revoke_session(record)
# Oppure normalizza tutto in stringhe al confine:
if str(record["session_id"]) == str(target):
revoke_session(record)Problema: uuid_obj.hex produce una stringa di 32 caratteri senza trattini. Se il codice a valle si aspetta il formato canonico di 36 caratteri con trattini (come la maggior parte delle API e dei database), lo rifiuterà o lo interpreterà silenziosamente in modo errato.
Soluzione: Usa str(uuid_obj) per il formato canonico di 36 caratteri a meno che tu non abbia un requisito esplicito per la forma hex compatta.
# Archivia "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" — senza trattini
payload = {"correlation_id": request_id.hex}# Archivia "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" — formato standard
payload = {"correlation_id": str(request_id)}Problema: random.random() non è crittograficamente sicuro, e secrets.token_hex(16) produce una stringa hex di 32 caratteri che non è un UUID valido — i validatori a valle che chiamano uuid.UUID() su di essa solleveranno ValueError.
Soluzione: Usa uuid.uuid4() ogni volta che il sistema ricevente si aspetta un identificatore in formato UUID. Usa secrets.token_hex() solo quando hai esplicitamente bisogno di un token casuale che non sia in formato UUID.
import random, secrets # Non è un UUID — fallirà la validazione uuid.UUID() request_id = secrets.token_hex(16) # "a1b2c3d4e5f6..." session_id = str(random.random()) # "0.8273..." — non è nemmeno vicino
import uuid request_id = str(uuid.uuid4()) # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" # UUID v4 valido, crittograficamente sicuro
Metodi di generazione UUID in Python — Confronto rapido
Tutti i metodi qui sotto producono identificatori a 128 bit, ma differiscono per sorgente di entropia, caratteristiche di privacy e necessità di installazione di terze parti.
Usa uuid.uuid4() per identificatori univoci generici in applicazioni web, sistemi distribuiti e chiavi primarie di database quando l'ordinabilità non è richiesta. Usa uuid.uuid5() (o v3) per ID deterministici derivati da un namespace e un nome noti — ad esempio, generare un ID stabile per un URL canonico. Passa a uuid_utils.uuid7() quando hai bisogno di ID ordinati per tempo per gli indici del database (evita le divisioni di pagina negli indici B-tree ad alto tasso di inserimento). Scegli uuid_utils.uuid4() quando la velocità di generazione grezza è il collo di bottiglia.
UUID v4 vs UUID v7 — Quale usare?
La domanda pratica più comune è se usare UUID v4 o il più recente UUID v7 per le chiavi primarie del database. La risposta breve è: usa UUID v4 di default; passa a UUID v7 solo quando la frammentazione degli indici è un problema misurato.
I valori UUID v4 sono completamente casuali, il che significa che gli inserimenti atterrano in posizioni casuali in un indice B-tree. A tassi di inserimento moderati (da centinaia a poche migliaia al secondo) questo va bene — l'indice entra nel buffer pool e le scritture casuali sono economiche. A tassi di inserimento molto elevati, il posizionamento casuale causa frequenti divisioni di pagina e cache miss, aumentando l'amplificazione in scrittura e rallentando le query.
UUID v7 incorpora un timestamp Unix con precisione al millisecondo nei bit più significativi, così le righe inserite vicine nel tempo atterrano anche vicine nell'indice. Questo dona agli indici B-tree (PostgreSQL, MySQL, SQLite) un comportamento simile a un intero auto-incrementale: le nuove righe si aggiungono sempre alla fine dell'indice, eliminando le divisioni di pagina. Il compromesso è che UUID v7 codifica un timestamp, che rivela il momento di creazione — evitalo per ID rivolti agli utenti dove il momento di creazione è sensibile.
In Python, UUID v7 non è ancora nella libreria standard (a partire da Python 3.12). Generalo con pip install uuid-utils e chiama uuid_utils.uuid7(). Restituisce un oggetto con lo stesso set di attributi di uuid.UUID, quindi la migrazione da v4 è una modifica su una riga nella factory degli ID.
Per un'alternativa con un solo clic senza alcuna configurazione Python, incolla la tua stringa UUID nel generatore e validatore UUID v4 — genera, valida e decodifica tutti i campi nel browser.
Domande frequenti
Come si genera un UUID v4 in Python?
Chiama uuid.uuid4() dal modulo uuid integrato di Python. Restituisce un oggetto UUID — convertilo in stringa con str() quando hai bisogno di una rappresentazione testuale. Il modulo è incluso nella libreria standard, quindi non è necessario installare nulla con pip.
import uuid session_id = uuid.uuid4() print(session_id) # es. 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e print(str(session_id)) # stessa stringa canonica print(session_id.hex) # 3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e (senza trattini)
Qual è la differenza tra uuid.uuid4() e str(uuid.uuid4())?
uuid.uuid4() restituisce un oggetto UUID con attributi come .hex, .bytes, .int e .version. str(uuid.uuid4()) converte immediatamente quell'oggetto in una stringa canonica di 36 caratteri, scartando l'oggetto. Mantieni l'oggetto se hai bisogno di più rappresentazioni; convertilo in stringa al momento in cui passi il valore a un payload JSON, a un database o a un header HTTP.
import uuid u = uuid.uuid4() print(type(u)) # <class 'uuid.UUID'> print(u.version) # 4 print(u.hex) # hex a 32 caratteri, senza trattini print(u.bytes) # binario di 16 byte print(str(u)) # stringa canonica di 36 caratteri con trattini
uuid.uuid4() è crittograficamente sicuro?
Sì. uuid.uuid4() di Python usa internamente os.urandom(), che legge dal generatore di numeri casuali crittograficamente sicuro del sistema operativo (/dev/urandom su Linux/macOS, CryptGenRandom su Windows). I 122 bit casuali rendono la probabilità di collisione trascurabile per qualsiasi carico di lavoro realistico. Non confonderlo con random.random(), che non è crittograficamente sicuro.
import uuid, os # uuid4 internamente chiama os.urandom(16) raw = os.urandom(16) # uuid4 imposta i bit di versione e variante prima di restituire il risultato u = uuid.UUID(bytes=raw, version=4) print(u) # UUID v4 valido da byte casuali grezzi
Come si verifica che una stringa sia un UUID v4 valido in Python?
Analizza con uuid.UUID() e controlla l'attributo .version. Se la stringa non è un UUID valido, uuid.UUID() solleva un ValueError — intercettalo per gestire l'input non valido. Questo valida anche che il formato (trattini, lunghezza) sia corretto.
import uuid
def is_valid_uuid4(value: str) -> bool:
try:
u = uuid.UUID(value)
return u.version == 4
except ValueError:
return False
print(is_valid_uuid4("3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e")) # True
print(is_valid_uuid4("not-a-uuid")) # False
print(is_valid_uuid4("3b1f8a9d-2c4e-1f6a-8b0d-5e7c9f1a3d2e")) # False (v1, non v4)Come si archiviano gli UUID in un database PostgreSQL o SQLite da Python?
Con PostgreSQL (tramite psycopg2 o asyncpg), passa direttamente l'oggetto UUID — il driver lo adatta al tipo UUID nativo. Con SQLite, che non ha un tipo UUID nativo, archivia come TEXT usando str(uuid_obj) o come BLOB usando uuid_obj.bytes. SQLAlchemy ha un tipo di colonna UUID che gestisce questo automaticamente tra i vari dialetti.
import uuid
import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE events (id TEXT PRIMARY KEY, name TEXT)")
event_id = uuid.uuid4()
conn.execute("INSERT INTO events VALUES (?, ?)", (str(event_id), "user_signup"))
conn.commit()
row = conn.execute("SELECT * FROM events").fetchone()
# Ricostruisci l'oggetto UUID dalla stringa archiviata
retrieved_id = uuid.UUID(row[0])
print(retrieved_id.version) # 4È possibile generare più UUID contemporaneamente in Python?
Sì — usa una list comprehension o un generator. Ogni chiamata a uuid.uuid4() è indipendente e garantisce di produrre un valore distinto. Per la generazione in blocco dove la velocità è importante, uuid-utils (implementato in Rust) è circa 10 volte più veloce della libreria standard.
import uuid
# Genera 5 trace ID univoci per una richiesta batch
trace_ids = [str(uuid.uuid4()) for _ in range(5)]
for tid in trace_ids:
print(tid)
# Ogni riga è un UUID v4 distintoStrumenti correlati
- →UUID v4 Generator — Genera valori UUID v4 istantaneamente nel browser — senza bisogno di un ambiente Python. Copia un singolo valore o generane centinaia in blocco.
- →UUID v7 Generator — Genera valori UUID v7 ordinati per tempo — ordinabili per data di creazione, ideali come chiavi primarie nei database dove la frammentazione degli indici è un problema.
- →UUID Decoder — Ispeziona qualsiasi UUID — versione, variante, timestamp (v1/v7) e campi node — senza scrivere un parser da zero.
- →JWT Decoder — Decodifica e ispeziona i token JWT, che spesso contengono claim UUID come subject (sub) o identificatori jti insieme agli UUID di sessione.
Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.
Dmitri is a DevOps engineer who relies on Python as his primary scripting and automation language. He builds internal tooling, CI/CD pipelines, and infrastructure automation scripts that run in production across distributed teams. He writes about the Python standard library, subprocess management, file processing, encoding utilities, and the practical shell-adjacent Python that DevOps engineers use every day.