summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorFederico Caselli <cfederico87@gmail.com>2022-11-27 18:11:34 +0100
committerMike Bayer <mike_mp@zzzcomputing.com>2022-11-29 17:49:27 -0500
commit9c9fd31bcea3beaed6d14fde639e65f6b43bea09 (patch)
tree2eef4b31c1f89f364c9bf15fdf153a4aad0f98c6 /doc
parent78833af4e650d37e6257cfbb541e4db56e2a285f (diff)
downloadsqlalchemy-9c9fd31bcea3beaed6d14fde639e65f6b43bea09.tar.gz
Improve support for enum in mapped classes
Add a new system by which TypeEngine objects have some say in how the declarative type registry interprets them. The Enum datatype is the primary target for this but it is hoped the system may be useful for other types as well. Fixes: #8859 Change-Id: I15ac3daee770408b5795746f47c1bbd931b7d26d
Diffstat (limited to 'doc')
-rw-r--r--doc/build/changelog/unreleased_20/8859.rst16
-rw-r--r--doc/build/orm/declarative_tables.rst100
2 files changed, 116 insertions, 0 deletions
diff --git a/doc/build/changelog/unreleased_20/8859.rst b/doc/build/changelog/unreleased_20/8859.rst
new file mode 100644
index 000000000..85e4be422
--- /dev/null
+++ b/doc/build/changelog/unreleased_20/8859.rst
@@ -0,0 +1,16 @@
+.. change::
+ :tags: usecase, orm
+ :tickets: 8859
+
+ Added support custom user-defined types which extend the Python
+ ``enum.Enum`` base class to be resolved automatically
+ to SQLAlchemy :class:`.Enum` SQL types, when using the Annotated
+ Declarative Table feature. The feature is made possible through new
+ lookup features added to the ORM type map feature, and includes support
+ for changing the arguments of the :class:`.Enum` that's generated by
+ default as well as setting up specific ``enum.Enum`` types within
+ the map with specific arguments.
+
+ .. seealso::
+
+ :ref:`orm_declarative_mapped_column_enums`
diff --git a/doc/build/orm/declarative_tables.rst b/doc/build/orm/declarative_tables.rst
index 475813f81..806a6897f 100644
--- a/doc/build/orm/declarative_tables.rst
+++ b/doc/build/orm/declarative_tables.rst
@@ -369,6 +369,106 @@ while still being able to use succinct annotation-only :func:`_orm.mapped_column
configurations. There are two more levels of Python-type configurability
available beyond this, described in the next two sections.
+.. _orm_declarative_mapped_column_enums:
+
+Using Python ``Enum`` types in the type map
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 2.0.0b4
+
+User-defined Python types which derive from the Python built-in ``enum.Enum``
+class are automatically linked to the SQLAlchemy :class:`.Enum` datatype
+when used in an ORM declarative mapping::
+
+ import enum
+
+ from sqlalchemy.orm import DeclarativeBase
+ from sqlalchemy.orm import Mapped
+ from sqlalchemy.orm import mapped_column
+
+
+ class Base(DeclarativeBase):
+ pass
+
+
+ class Status(enum.Enum):
+ PENDING = "pending"
+ RECEIVED = "received"
+ COMPLETED = "completed"
+
+
+ class SomeClass(Base):
+ __tablename__ = "some_table"
+
+ id: Mapped[int] = mapped_column(primary_key=True)
+ status: Mapped[Status]
+
+In the above example, the mapped attribute ``SomeClass.status`` will be
+linked to a :class:`.Column` with the datatype of ``Enum(Status)``.
+We can see this for example in the CREATE TABLE output for the PostgreSQL
+database:
+
+.. sourcecode:: sql
+
+ CREATE TYPE status AS ENUM ('PENDING', 'RECEIVED', 'COMPLETED')
+
+ CREATE TABLE some_table (
+ id SERIAL NOT NULL,
+ status status NOT NULL,
+ PRIMARY KEY (id)
+ )
+
+The entry used in :paramref:`_orm.registry.type_annotation_map` links the
+base ``enum.Enum`` Python type to the SQLAlchemy :class:`.Enum` SQL
+type, using a special form which indicates to the :class:`.Enum` datatype
+that it should automatically configure itself against an arbitrary enumerated
+type. This configuration, which is implicit by default, would be indicated
+explicitly as::
+
+ import enum
+ import sqlalchemy
+
+
+ class Base(DeclarativeBase):
+ type_annotation_map = {enum.Enum: sqlalchemy.Enum(enum.Enum)}
+
+The resolution logic within Declarative is able to resolve subclasses
+of ``enum.Enum``, in the above example the custom ``Status`` enumeration,
+to match the ``enum.Enum`` entry in the
+:paramref:`_orm.registry.type_annotation_map` dictionary. The :class:`.Enum`
+SQL type then knows how to produce a configured version of itself with the
+appropriate settings, including default string length.
+
+In order to modify the configuration of the :class:`.enum.Enum` datatype used
+in this mapping, use the above form, indicating additional arguments. For
+example, to use "non native enumerations" on all backends, the
+:paramref:`.Enum.native_enum` parameter may be set to False for all types::
+
+ import enum
+ import sqlalchemy
+
+
+ class Base(DeclarativeBase):
+ type_annotation_map = {enum.Enum: sqlalchemy.Enum(enum.Enum, native_enum=False)}
+
+To use a specific configuration for a specific ``enum.Enum`` subtype, such
+as setting the string length to 50 when using the example ``Status``
+datatype::
+
+ import enum
+ import sqlalchemy
+
+
+ class Status(enum.Enum):
+ PENDING = "pending"
+ RECEIVED = "received"
+ COMPLETED = "completed"
+
+
+ class Base(DeclarativeBase):
+ type_annotation_map = {
+ Status: sqlalchemy.Enum(Status, length=50, native_enum=False)
+ }
.. _orm_declarative_mapped_column_type_map_pep593: