summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/mutable.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-11-25 14:29:30 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2022-11-29 19:25:59 -0500
commit3e3e3ab0d46b8912649afc7c3eb63b76c19d93fe (patch)
treef2c5b6fde3c6679138b255056d1b38db2ac67fc6 /lib/sqlalchemy/ext/mutable.py
parent78833af4e650d37e6257cfbb541e4db56e2a285f (diff)
downloadsqlalchemy-3e3e3ab0d46b8912649afc7c3eb63b76c19d93fe.tar.gz
annotated / DC forms for association proxy
Added support for the :func:`.association_proxy` extension function to take part within Python ``dataclasses`` configuration, when using the native dataclasses feature described at :ref:`orm_declarative_native_dataclasses`. Included are attribute-level arguments including :paramref:`.association_proxy.init` and :paramref:`.association_proxy.default_factory`. Documentation for association proxy has also been updated to use "Annotated Declarative Table" forms within examples, including type annotations used for :class:`.AssocationProxy` itself. Also modernized documentation examples in sqlalchemy.ext.mutable, which was not up to date even for 1.4 style code. Corrected typing for relationship(secondary) where "secondary" accepts a callable (i.e. lambda) as well Fixes: #8878 Fixes: #8876 Fixes: #8880 Change-Id: Ibd4f3591155a89f915713393e103e61cc072ed57
Diffstat (limited to 'lib/sqlalchemy/ext/mutable.py')
-rw-r--r--lib/sqlalchemy/ext/mutable.py47
1 files changed, 25 insertions, 22 deletions
diff --git a/lib/sqlalchemy/ext/mutable.py b/lib/sqlalchemy/ext/mutable.py
index f9ed17efc..242f5ee8f 100644
--- a/lib/sqlalchemy/ext/mutable.py
+++ b/lib/sqlalchemy/ext/mutable.py
@@ -111,34 +111,27 @@ Above, :meth:`~.Mutable.as_mutable` returns an instance of ``JSONEncodedDict``
attributes which are mapped against this type. Below we establish a simple
mapping against the ``my_data`` table::
- from sqlalchemy import mapper
+ from sqlalchemy.orm import DeclarativeBase
+ from sqlalchemy.orm import Mapped
+ from sqlalchemy.orm import mapped_column
- class MyDataClass:
+ class Base(DeclarativeBase):
pass
- # associates mutation listeners with MyDataClass.data
- mapper(MyDataClass, my_data)
+ class MyDataClass(Base):
+ __tablename__ = 'my_data'
+ id: Mapped[int] = mapped_column(primary_key=True)
+ data: Mapped[dict[str, str]] = mapped_column(MutableDict.as_mutable(JSONEncodedDict))
The ``MyDataClass.data`` member will now be notified of in place changes
to its value.
-There's no difference in usage when using declarative::
-
- from sqlalchemy.ext.declarative import declarative_base
-
- Base = declarative_base()
-
- class MyDataClass(Base):
- __tablename__ = 'my_data'
- id = Column(Integer, primary_key=True)
- data = Column(MutableDict.as_mutable(JSONEncodedDict))
-
Any in-place changes to the ``MyDataClass.data`` member
will flag the attribute as "dirty" on the parent object::
>>> from sqlalchemy.orm import Session
- >>> sess = Session()
+ >>> sess = Session(some_engine)
>>> m1 = MyDataClass(data={'value1':'foo'})
>>> sess.add(m1)
>>> sess.commit()
@@ -154,12 +147,19 @@ of ``JSONEncodedDict`` in one step, using
of ``MutableDict`` in all mappings unconditionally, without
the need to declare it individually::
+ from sqlalchemy.orm import DeclarativeBase
+ from sqlalchemy.orm import Mapped
+ from sqlalchemy.orm import mapped_column
+
MutableDict.associate_with(JSONEncodedDict)
+ class Base(DeclarativeBase):
+ pass
+
class MyDataClass(Base):
__tablename__ = 'my_data'
- id = Column(Integer, primary_key=True)
- data = Column(JSONEncodedDict)
+ id: Mapped[int] = mapped_column(primary_key=True)
+ data: Mapped[dict[str, str]] = mapped_column(JSONEncodedDict)
Supporting Pickling
@@ -208,15 +208,18 @@ an event when a mutable scalar emits a change event. This event handler
is called when the :func:`.attributes.flag_modified` function is called
from within the mutable extension::
- from sqlalchemy.ext.declarative import declarative_base
+ from sqlalchemy.orm import DeclarativeBase
+ from sqlalchemy.orm import Mapped
+ from sqlalchemy.orm import mapped_column
from sqlalchemy import event
- Base = declarative_base()
+ class Base(DeclarativeBase):
+ pass
class MyDataClass(Base):
__tablename__ = 'my_data'
- id = Column(Integer, primary_key=True)
- data = Column(MutableDict.as_mutable(JSONEncodedDict))
+ id: Mapped[int] = mapped_column(primary_key=True)
+ data: Mapped[dict[str, str]] = mapped_column(MutableDict.as_mutable(JSONEncodedDict))
@event.listens_for(MyDataClass.data, "modified")
def modified_json(instance, initiator):