]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Document user-defined functions for sqlite
authorGord Thompson <gord@gordthompson.com>
Wed, 29 Jun 2022 13:38:38 +0000 (07:38 -0600)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 29 Sep 2022 13:10:53 +0000 (09:10 -0400)
Change-Id: I64e4d4dce8c5f5aced3190f9e3682c630462a61e
(cherry picked from commit 48a0df55c1cfb8746eec8073c0feb05be1652665)

lib/sqlalchemy/dialects/sqlite/aiosqlite.py
lib/sqlalchemy/dialects/sqlite/pysqlite.py

index 9fc6d355ca87abc3b9872f8bee32853c4a6a4105..04adabfb6a142ad5f0001dc0bdb6bf6e0d6a4083 100644 (file)
@@ -34,6 +34,14 @@ This dialect should normally be used only with the
 The URL passes through all arguments to the ``pysqlite`` driver, so all
 connection arguments are the same as they are for that of :ref:`pysqlite`.
 
+.. _aiosqlite_udfs:
+
+User-Defined Functions
+----------------------
+
+aiosqlite extends pysqlite to support async, so we can create our own user-defined functions (UDFs)
+in Python and use them directly in SQLite queries as described here: :ref:`pysqlite_udfs`.
+
 
 """  # noqa
 
index 1aae5610dfc6c1f28d8b6909d9152d1f9bcd4862..d9fa9413e78dba231d2161415d97293d2bdb015c 100644 (file)
@@ -399,6 +399,39 @@ by adding the desired locking mode to our ``"BEGIN"``::
     `sqlite3 module breaks transactions and potentially corrupts data <https://bugs.python.org/issue10740>`_ -
     on the Python bug tracker
 
+.. _pysqlite_udfs:
+
+User-Defined Functions
+----------------------
+
+pysqlite supports a `create_function() <https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.create_function>`_
+method that allows us to create our own user-defined functions (UDFs) in Python and use them directly in SQLite queries.
+These functions are registered with a specific DBAPI Connection.
+
+SQLAlchemy uses connection pooling with file-based SQLite databases, so we need to ensure that the UDF is attached to the
+connection when it is created. That is accomplished with an event listener::
+
+    from sqlalchemy import create_engine
+    from sqlalchemy import event
+    from sqlalchemy import text
+
+
+    def udf():
+        return "udf-ok"
+
+
+    engine = create_engine("sqlite:///./db_file")
+
+
+    @event.listens_for(engine, "connect")
+    def connect(conn, rec):
+        conn.create_function("udf", 0, udf)
+
+
+    for i in range(5):
+        with engine.connect() as conn:
+            print(conn.scalar(text("SELECT UDF()")))
+
 
 """  # noqa