summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2022-11-30 16:35:41 +0000
committerGerrit Code Review <gerrit@ci3.zzzcomputing.com>2022-11-30 16:35:41 +0000
commitc440c920aecd6593974e5a0d37cdb9069e5d3e57 (patch)
tree1ae88befaef5da0bc1e48c8fde5c05e59cbd9dee /doc
parent1057b47bca2522e45d9621a709d033aa4fb88888 (diff)
parent9c9fd31bcea3beaed6d14fde639e65f6b43bea09 (diff)
downloadsqlalchemy-c440c920aecd6593974e5a0d37cdb9069e5d3e57.tar.gz
Merge "Improve support for enum in mapped classes" into main
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: