lol
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -44,6 +44,36 @@ 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`.
|
||||
|
||||
.. _aiosqlite_serializable:
|
||||
|
||||
Serializable isolation / Savepoints / Transactional DDL (asyncio version)
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Similarly to pysqlite, aiosqlite does not support SAVEPOINT feature.
|
||||
|
||||
The solution is similar to :ref:`pysqlite_serializable`. This is achieved by the event listeners in async::
|
||||
|
||||
from sqlalchemy import create_engine, event
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
|
||||
engine = create_async_engine("sqlite+aiosqlite:///myfile.db")
|
||||
|
||||
@event.listens_for(engine.sync_engine, "connect")
|
||||
def do_connect(dbapi_connection, connection_record):
|
||||
# disable aiosqlite's emitting of the BEGIN statement entirely.
|
||||
# also stops it from emitting COMMIT before any DDL.
|
||||
dbapi_connection.isolation_level = None
|
||||
|
||||
@event.listens_for(engine.sync_engine, "begin")
|
||||
def do_begin(conn):
|
||||
# emit our own BEGIN
|
||||
conn.exec_driver_sql("BEGIN")
|
||||
|
||||
.. warning:: When using the above recipe, it is advised to not use the
|
||||
:paramref:`.Connection.execution_options.isolation_level` setting on
|
||||
:class:`_engine.Connection` and :func:`_sa.create_engine`
|
||||
with the SQLite driver,
|
||||
as this function necessarily will also alter the ".isolation_level" setting.
|
||||
|
||||
""" # noqa
|
||||
|
||||
@@ -60,6 +90,9 @@ from ...util.concurrency import await_only
|
||||
|
||||
|
||||
class AsyncAdapt_aiosqlite_cursor:
|
||||
# TODO: base on connectors/asyncio.py
|
||||
# see #10415
|
||||
|
||||
__slots__ = (
|
||||
"_adapt_connection",
|
||||
"_connection",
|
||||
@@ -151,6 +184,8 @@ class AsyncAdapt_aiosqlite_cursor:
|
||||
|
||||
|
||||
class AsyncAdapt_aiosqlite_ss_cursor(AsyncAdapt_aiosqlite_cursor):
|
||||
# TODO: base on connectors/asyncio.py
|
||||
# see #10415
|
||||
__slots__ = "_cursor"
|
||||
|
||||
server_side = True
|
||||
|
||||
@@ -215,7 +215,7 @@ by *not even emitting BEGIN* until the first write operation.
|
||||
SQLite's transactional scope is impacted by unresolved
|
||||
issues in the pysqlite driver, which defers BEGIN statements to a greater
|
||||
degree than is often feasible. See the section :ref:`pysqlite_serializable`
|
||||
for techniques to work around this behavior.
|
||||
or :ref:`aiosqlite_serializable` for techniques to work around this behavior.
|
||||
|
||||
.. seealso::
|
||||
|
||||
@@ -273,8 +273,9 @@ won't work at all with pysqlite unless workarounds are taken.
|
||||
.. warning::
|
||||
|
||||
SQLite's SAVEPOINT feature is impacted by unresolved
|
||||
issues in the pysqlite driver, which defers BEGIN statements to a greater
|
||||
degree than is often feasible. See the section :ref:`pysqlite_serializable`
|
||||
issues in the pysqlite and aiosqlite drivers, which defer BEGIN statements
|
||||
to a greater degree than is often feasible. See the sections
|
||||
:ref:`pysqlite_serializable` and :ref:`aiosqlite_serializable`
|
||||
for techniques to work around this behavior.
|
||||
|
||||
Transactional DDL
|
||||
@@ -843,7 +844,7 @@ Reflecting internal schema tables
|
||||
----------------------------------
|
||||
|
||||
Reflection methods that return lists of tables will omit so-called
|
||||
"SQLite internal schema object" names, which are referred towards by SQLite
|
||||
"SQLite internal schema object" names, which are considered by SQLite
|
||||
as any object name that is prefixed with ``sqlite_``. An example of
|
||||
such an object is the ``sqlite_sequence`` table that's generated when
|
||||
the ``AUTOINCREMENT`` column parameter is used. In order to return
|
||||
@@ -1318,6 +1319,9 @@ class SQLiteCompiler(compiler.SQLCompiler):
|
||||
def visit_char_length_func(self, fn, **kw):
|
||||
return "length%s" % self.function_argspec(fn)
|
||||
|
||||
def visit_aggregate_strings_func(self, fn, **kw):
|
||||
return "group_concat%s" % self.function_argspec(fn)
|
||||
|
||||
def visit_cast(self, cast, **kwargs):
|
||||
if self.dialect.supports_cast:
|
||||
return super().visit_cast(cast, **kwargs)
|
||||
@@ -2444,10 +2448,16 @@ class SQLiteDialect(default.DefaultDialect):
|
||||
if table_data is None:
|
||||
# system tables, etc.
|
||||
return
|
||||
|
||||
# note that we already have the FKs from PRAGMA above. This whole
|
||||
# regexp thing is trying to locate additional detail about the
|
||||
# FKs, namely the name of the constraint and other options.
|
||||
# so parsing the columns is really about matching it up to what
|
||||
# we already have.
|
||||
FK_PATTERN = (
|
||||
r"(?:CONSTRAINT (\w+) +)?"
|
||||
r"FOREIGN KEY *\( *(.+?) *\) +"
|
||||
r'REFERENCES +(?:(?:"(.+?)")|([a-z0-9_]+)) *\((.+?)\) *'
|
||||
r'REFERENCES +(?:(?:"(.+?)")|([a-z0-9_]+)) *\( *((?:(?:"[^"]+"|[a-z0-9_]+) *(?:, *)?)+)\) *' # noqa: E501
|
||||
r"((?:ON (?:DELETE|UPDATE) "
|
||||
r"(?:SET NULL|SET DEFAULT|CASCADE|RESTRICT|NO ACTION) *)*)"
|
||||
r"((?:NOT +)?DEFERRABLE)?"
|
||||
|
||||
Reference in New Issue
Block a user