]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
doc fixes
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 10 Feb 2022 02:59:43 +0000 (21:59 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 10 Feb 2022 03:37:24 +0000 (22:37 -0500)
* clarify merge behavior for non-present attributes,
  references #7687
* fix AsyncSession in async_scoped_session documentation,
  name the scoped session AsyncScopedSession, fixes: #7671
* Use non-deprecated execute() style in sqltypes JSON examples,
  fixes: #7633
* Add note regarding mitigation for
  https://github.com/MagicStack/asyncpg/issues/727,
  fixes #7245

Fixes: #7671
Fixes: #7633
Fixes: #7245
Change-Id: Ic40b4378ca321367a912864f4eddfdd9714fe217

doc/build/orm/extensions/asyncio.rst
doc/build/orm/session_state_management.rst
lib/sqlalchemy/dialects/postgresql/asyncpg.py
lib/sqlalchemy/sql/sqltypes.py

index 4aff3130b29c44f7d7a2941a9aad30ec8be474a1..5d552b419b3ee2f0e263db205351cf9a5ad7da40 100644 (file)
@@ -712,10 +712,10 @@ constructor::
     from sqlalchemy.ext.asyncio import async_scoped_session
     from sqlalchemy.ext.asyncio import AsyncSession
 
-    async_session_factory = sessionmaker(some_async_engine, class_=_AsyncSession)
-    AsyncSession = async_scoped_session(async_session_factory, scopefunc=current_task)
+    async_session_factory = sessionmaker(some_async_engine, class_=AsyncSession)
+    AsyncScopedSession = async_scoped_session(async_session_factory, scopefunc=current_task)
 
-    some_async_session = AsyncSession()
+    some_async_session = AsyncScopedSession()
 
 :class:`_asyncio.async_scoped_session` also includes **proxy
 behavior** similar to that of :class:`.scoped_session`, which means it can be
@@ -728,10 +728,10 @@ the usual ``await`` keywords are necessary, including for the
        some_async_session.add(some_object)
 
        # use the AsyncSession via the context-local proxy
-       await AsyncSession.commit()
+       await AsyncScopedSession.commit()
 
        # "remove" the current proxied AsyncSession for the local context
-       await AsyncSession.remove()
+       await AsyncScopedSession.remove()
 
 .. versionadded:: 1.4.19
 
index 64efffd761485f41a9eee3d7c6700bbb9d613cbd..47b4fbe7fd8304f0a5b6a25951b9fba1a67593b2 100644 (file)
@@ -204,11 +204,14 @@ When given an instance, it follows these steps:
   key if not located locally.
 * If the given instance has no primary key, or if no instance can be found
   with the primary key given, a new instance is created.
-* The state of the given instance is then copied onto the located/newly
-  created instance.    For attributes which are present on the source
-  instance, the value is transferred to the target instance.  For mapped
-  attributes which aren't present on the source, the attribute is
-  expired on the target instance, discarding its existing value.
+* The state of the given instance is then copied onto the located/newly created
+  instance. For attribute values which are present on the source instance, the
+  value is transferred to the target instance. For attribute values that aren't
+  present on the source instance, the corresponding attribute on the target
+  instance is :term:`expired` from memory, which discards any locally
+  present value from the target instance for that attribute, but no
+  direct modification is made to the database-persisted value for that
+  attribute.
 
   If the ``load=True`` flag is left at its default,
   this copy process emits events and will load the target object's
index 7dbcfa357ca46c8581601850260064025d4cfbd4..4c3c47ba6fd52c6827d739d4c86cd894e7676e56 100644 (file)
@@ -96,6 +96,25 @@ To disable the prepared statement cache, use a value of zero::
    stale, nor can it retry the statement as the PostgreSQL transaction is
    invalidated when these errors occur.
 
+Disabling the PostgreSQL JIT to improve ENUM datatype handling
+---------------------------------------------------------------
+
+Asyncpg has an `issue <https://github.com/MagicStack/asyncpg/issues/727>`_ when
+using PostgreSQL ENUM datatypes, where upon the creation of new database
+connections, an expensive query may be emitted in order to retrieve metadata
+regarding custom types which has been shown to negatively affect performance.
+To mitigate this issue, the PostgreSQL "jit" setting may be disabled from the
+client using this setting passed to :func:`_asyncio.create_async_engine`::
+
+    engine = create_async_engine(
+        "postgresql+asyncpg://user:password@localhost/tmp",
+        connect_args={"server_settings": {"jit": "off"}},
+    )
+
+.. seealso::
+
+    https://github.com/MagicStack/asyncpg/issues/727
+
 """  # noqa
 
 import collections
index 575f402c3fd2d5acf4940046ca584aebc60cc728..0ec771cb436a8efdbeb73d8fa4427247679e445c 100644 (file)
@@ -1904,7 +1904,7 @@ class JSON(Indexable, TypeEngine[Any]):
         with engine.connect() as conn:
             conn.execute(
                 data_table.insert(),
-                data = {"key1": "value1", "key2": "value2"}
+                {"data": {"key1": "value1", "key2": "value2"}}
             )
 
     **JSON-Specific Expression Operators**
@@ -2000,20 +2000,22 @@ class JSON(Indexable, TypeEngine[Any]):
 
     **Support for JSON null vs. SQL NULL**
 
-    When working with NULL values, the :class:`_types.JSON`
-    type recommends the
+    When working with NULL values, the :class:`_types.JSON` type recommends the
     use of two specific constants in order to differentiate between a column
-    that evaluates to SQL NULL, e.g. no value, vs. the JSON-encoded string
-    of ``"null"``.   To insert or select against a value that is SQL NULL,
-    use the constant :func:`.null`::
+    that evaluates to SQL NULL, e.g. no value, vs. the JSON-encoded string of
+    ``"null"``. To insert or select against a value that is SQL NULL, use the
+    constant :func:`.null`. This symbol may be passed as a parameter value
+    specifically when using the :class:`_types.JSON` datatype, which contains
+    special logic that interprets this symbol to mean that the column value
+    should be SQL NULL as opposed to JSON ``"null"``::
 
         from sqlalchemy import null
-        conn.execute(table.insert(), json_value=null())
+        conn.execute(table.insert(), {"json_value": null()})
 
     To insert or select against a value that is JSON ``"null"``, use the
     constant :attr:`_types.JSON.NULL`::
 
-        conn.execute(table.insert(), json_value=JSON.NULL)
+        conn.execute(table.insert(), {"json_value": JSON.NULL})
 
     The :class:`_types.JSON` type supports a flag
     :paramref:`_types.JSON.none_as_null` which when set to True will result
@@ -2114,12 +2116,14 @@ class JSON(Indexable, TypeEngine[Any]):
         """Construct a :class:`_types.JSON` type.
 
         :param none_as_null=False: if True, persist the value ``None`` as a
-         SQL NULL value, not the JSON encoding of ``null``.   Note that
-         when this flag is False, the :func:`.null` construct can still
-         be used to persist a NULL value::
+         SQL NULL value, not the JSON encoding of ``null``. Note that when this
+         flag is False, the :func:`.null` construct can still be used to
+         persist a NULL value, which may be passed directly as a parameter
+         value that is specially interpreted by the :class:`_types.JSON` type
+         as SQL NULL::
 
              from sqlalchemy import null
-             conn.execute(table.insert(), data=null())
+             conn.execute(table.insert(), {"data": null()})
 
          .. note::
 
@@ -2461,7 +2465,7 @@ class ARRAY(
 
         connection.execute(
                 mytable.insert(),
-                data=[1,2,3]
+                {"data": [1,2,3]}
         )
 
     The :class:`_types.ARRAY` type can be constructed given a fixed number