From: Federico Caselli Date: Mon, 11 Sep 2023 20:57:20 +0000 (+0200) Subject: Improve the GUID typedecorator example X-Git-Tag: rel_2_0_21~12^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=861899953ad2d6cd26db4385752c591462b3c167;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Improve the GUID typedecorator example Change-Id: I92909b1262f994a3ff0dd201bc87612ff1d37822 References: #10336 --- diff --git a/doc/build/core/custom_types.rst b/doc/build/core/custom_types.rst index d084b428c8..6ae9e066ac 100644 --- a/doc/build/core/custom_types.rst +++ b/doc/build/core/custom_types.rst @@ -171,12 +171,20 @@ denormalize:: Backend-agnostic GUID Type ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Receives and returns Python uuid() objects. Uses the PG UUID type -when using PostgreSQL, CHAR(32) on other backends, storing them -in stringified hex format. Can be modified to store -binary in CHAR(16) if desired:: - +.. note:: Since version 2.0 the built-in :class:`_types.Uuid` type that + behaves similarly should be preferred. This example is presented + just as an example of a type decorator that recieves and returns + python objects. + +Receives and returns Python uuid() objects. +Uses the PG UUID type when using PostgreSQL, UNIQUEIDENTIFIER when using MSSQL, +CHAR(32) on other backends, storing them in stringified format. +The ``GUIDHyphens`` version stores the value with hyphens instead of just the hex +string, using a CHAR(36) type:: + + from operator import attrgetter from sqlalchemy.types import TypeDecorator, CHAR + from sqlalchemy.dialects.mssql import UNIQUEIDENTIFIER from sqlalchemy.dialects.postgresql import UUID import uuid @@ -184,31 +192,34 @@ binary in CHAR(16) if desired:: class GUID(TypeDecorator): """Platform-independent GUID type. - Uses PostgreSQL's UUID type, otherwise uses - CHAR(32), storing as stringified hex values. + Uses PostgreSQL's UUID type or MSSQL's UNIQUEIDENTIFIER, + otherwise uses CHAR(32), storing as stringified hex values. """ impl = CHAR cache_ok = True + _default_type = CHAR(32) + _uuid_as_str = attrgetter("hex") + def load_dialect_impl(self, dialect): if dialect.name == "postgresql": return dialect.type_descriptor(UUID()) + elif dialect.name == "mssql": + return dialect.type_descriptor(UNIQUEIDENTIFIER()) else: - return dialect.type_descriptor(CHAR(32)) + return dialect.type_descriptor(self._default_type) def process_bind_param(self, value, dialect): if value is None: return value - elif dialect.name == "postgresql": + elif dialect.name in ("postgresql", "mssql"): return str(value) else: if not isinstance(value, uuid.UUID): - return "%.32x" % uuid.UUID(value).int - else: - # hexstring - return "%.32x" % value.int + value = uuid.UUID(value) + return self._uuid_as_str(value) def process_result_value(self, value, dialect): if value is None: @@ -218,6 +229,18 @@ binary in CHAR(16) if desired:: value = uuid.UUID(value) return value + + class GUIDHyphens(GUID): + """Platform-independent GUID type. + + Uses PostgreSQL's UUID type or MSSQL's UNIQUEIDENTIFIER, + otherwise uses CHAR(36), storing as stringified uuid values. + + """ + + _default_type = CHAR(36) + _uuid_as_str = str + Linking Python ``uuid.UUID`` to the Custom Type for ORM mappings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/setup.cfg b/setup.cfg index 5c68605d08..bcfa98116b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -170,7 +170,7 @@ mariadb = mariadb+mysqldb://scott:tiger@127.0.0.1:3306/test mariadb_connector = mariadb+mariadbconnector://scott:tiger@127.0.0.1:3306/test mssql = mssql+pyodbc://scott:tiger^5HHH@mssql2017:1433/test?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes pymssql = mssql+pymssql://scott:tiger^5HHH@mssql2017:1433/test -docker_mssql = mssql+pyodbc://scott:tiger^5HHH@127.0.0.1:1433/test?driver=ODBC+Driver+17+for+SQL+Server +docker_mssql = mssql+pyodbc://scott:tiger^5HHH@127.0.0.1:1433/test?driver=ODBC+Driver+18+for+SQL+Server oracle = oracle+cx_oracle://scott:tiger@oracle18c/xe cxoracle = oracle+cx_oracle://scott:tiger@oracle18c/xe oracledb = oracle+oracledb://scott:tiger@oracle18c/xe