Gibt es eine Möglichkeit, eine Spalte (Primärschlüssel) als UUID in SQLAlchemy zu definieren, wenn PostgreSQL (Postgres) verwendet wird?
python
postgresql
orm
sqlalchemy
uuid
Vasil
quelle
quelle
Antworten:
Der Postgres-Dialekt von sqlalchemy unterstützt UUID-Spalten. Das ist einfach (und die Frage ist speziell postgres) - ich verstehe nicht, warum die anderen Antworten alle so kompliziert sind.
Hier ist ein Beispiel:
Achten Sie darauf, dass Sie die Übergabe an die Spaltendefinition nicht verpassen
callable
uuid.uuid4
, anstatt die Funktion selbst mit aufzurufenuuid.uuid4()
. Andernfalls haben Sie für alle Instanzen dieser Klasse den gleichen Skalarwert. Weitere Details hier :quelle
uuid.uuid4
.)Column(UUID(as_uuid=True) ...)
Column
undInteger
oben im Code-Snippet importiert wurden oder geändert wurden, um zu lesendb.Column
unddb.Integer
Ich habe das geschrieben und die Domain ist weg, aber hier ist der Mut ...
Unabhängig davon, wie meine Kollegen, die sich wirklich für das richtige Datenbankdesign interessieren, UUIDs und GUIDs, die für Schlüsselfelder verwendet werden, beurteilen. Ich finde oft, dass ich es tun muss. Ich denke, es hat einige Vorteile gegenüber der automatischen Erhöhung, die es wert machen.
Ich habe in den letzten Monaten einen UUID-Spaltentyp verfeinert und ich denke, ich habe ihn endlich solide.
Ich bin der Meinung, dass das Speichern als Binärdatei (16 Byte) effizienter sein sollte als die Zeichenfolgendarstellung (36 Byte?). Und es scheint Anzeichen dafür zu geben, dass die Indizierung von 16-Byte-Blöcken in MySQL effizienter sein sollte als Zeichenfolgen. Ich würde sowieso nicht erwarten, dass es schlimmer wird.
Ein Nachteil, den ich festgestellt habe, ist, dass Sie zumindest in phpymyadmin keine Datensätze bearbeiten können, da implizit versucht wird, eine Zeichenkonvertierung für "select * from table where id = ..." durchzuführen, und es gibt verschiedene Anzeigeprobleme.
Davon abgesehen scheint alles gut zu funktionieren, und so werfe ich es da raus. Hinterlasse einen Kommentar, wenn du einen krassen Fehler siehst. Ich freue mich über Verbesserungsvorschläge.
Sofern mir nichts fehlt, funktioniert die obige Lösung, wenn die zugrunde liegende Datenbank einen UUID-Typ hat. Wenn dies nicht der Fall ist, werden beim Erstellen der Tabelle wahrscheinlich Fehler angezeigt. Die Lösung, die ich mir ausgedacht habe, war ursprünglich das Ziel von MSSqlServer und dann MySql. Daher denke ich, dass meine Lösung etwas flexibler ist, da sie auf MySQL und SQLite gut zu funktionieren scheint. Ich habe mich noch nicht darum gekümmert, Postgres zu überprüfen.
quelle
sqlalchemy.dialects.postgresql.UUID
direkt. siehe Backend-agnostischer GUID-TypSiehe auch das Rezept für den Backend-agnostischen GUID-Typ in der SQLAlchemy-Dokumentation für Spaltentypen.
quelle
Wenn Sie mit einer 'String'-Spalte mit UUID-Wert zufrieden sind, finden Sie hier eine einfache Lösung:
quelle
Ich habe das
UUIDType
aus demSQLAlchemy-Utils
Paket verwendet: http://sqlalchemy-utils.readthedocs.org/en/latest/data_types.html#module-sqlalchemy_utils.types.uuidquelle
raise InvalidStatus("notfound: {k}. (cls={cls})".format(k=k, cls=cls))
alchemyjsonschema.InvalidStatus: notfound: BINARY(16). (cls=<class 'sqlalchemy_utils.types.uuid.UUIDType'>)
NameError: name 'sqlalchemy_utils' is not defined
?SQLAlchemy-Utils
ist ein Paket von Drittanbietern, müssen Sie es zuerst installieren:pip install sqlalchemy-utils
Da Sie Postgres verwenden, sollte dies funktionieren:
quelle
Hier ist ein Ansatz, der auf der Backend-agnostischen GUID aus den SQLAlchemy-Dokumenten basiert , jedoch ein BINARY-Feld verwendet, um die UUIDs in Nicht-Postgresql-Datenbanken zu speichern.
quelle
Falls jemand interessiert ist, habe ich die Antwort von Tom Willis verwendet, aber es hat sich als nützlich erwiesen, der Konvertierung von uuid.UUID in der Methode process_bind_param eine Zeichenfolge hinzuzufügen
quelle
Sie könnten versuchen, einen benutzerdefinierten Typ zu schreiben , zum Beispiel:
quelle
types.TypeDecorator
anstelle vontypes.TypeEngine
. Hat einer der beiden Ansätze einen Vor- oder Nachteil gegenüber dem anderen?default=?
? zBColumn('id', UUID(), primary_key=True, default=<someautouuidgeneratingthing>)