g3dZddlZddlmZddlmZddlmZddlm Z dd l m Z dd l m Z dd l mZdd lmZdd lmZGddZGddeZGddeZGddeZGddZGddeZGdde ZeZy)a .. dialect:: sqlite+aiosqlite :name: aiosqlite :dbapi: aiosqlite :connectstring: sqlite+aiosqlite:///file_path :url: https://pypi.org/project/aiosqlite/ The aiosqlite dialect provides support for the SQLAlchemy asyncio interface running on top of pysqlite. aiosqlite is a wrapper around pysqlite that uses a background thread for each connection. It does not actually use non-blocking IO, as SQLite databases are not socket-based. However it does provide a working asyncio interface that's useful for testing and prototyping purposes. Using a special asyncio mediation layer, the aiosqlite dialect is usable as the backend for the :ref:`SQLAlchemy asyncio ` extension package. This dialect should normally be used only with the :func:`_asyncio.create_async_engine` engine creation function:: from sqlalchemy.ext.asyncio import create_async_engine engine = create_async_engine("sqlite+aiosqlite:///filename") 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`. .. _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. .. _aiosqlite_pooling: Pooling Behavior ---------------- The SQLAlchemy ``aiosqlite`` DBAPI establishes the connection pool differently based on the kind of SQLite database that's requested: * When a ``:memory:`` SQLite database is specified, the dialect by default will use :class:`.StaticPool`. This pool maintains a single connection, so that all access to the engine use the same ``:memory:`` database. * When a file-based database is specified, the dialect will use :class:`.AsyncAdaptedQueuePool` as the source of connections. .. versionchanged:: 2.0.38 SQLite file database engines now use :class:`.AsyncAdaptedQueuePool` by default. Previously, :class:`.NullPool` were used. The :class:`.NullPool` class may be used by specifying it via the :paramref:`_sa.create_engine.poolclass` parameter. N)deque)partial)SQLiteExecutionContext)SQLiteDialect_pysqlite)pool)util)AdaptedConnection)await_fallback) await_onlycNeZdZdZdZdZdZd dZdZdZ d Z d Z d d Z d Z y)AsyncAdapt_aiosqlite_cursor)_adapt_connection _connection descriptionawait__rows arraysizerowcount lastrowidFc||_|j|_|j|_d|_d|_d|_t |_y)Nr)rrrrrrrr)selfadapt_connections U/opt/hc_python/lib64/python3.12/site-packages/sqlalchemy/dialects/sqlite/aiosqlite.py__init__z$AsyncAdapt_aiosqlite_cursor.__init__sD!1+77&--  W c8|jjyN)rclearrs rclosez!AsyncAdapt_aiosqlite_cursor.closes rNc |j|jj}|!|j|j|n!|j|j|||jrY|j|_dx|_|_|jsWt|j|j|_ n)d|_|j |_|j |_|js |j|jy||_ y#t$r%}|jj|Yd}~yd}~wwxYw)Nr)rrcursorexecuterrr server_siderfetchallrr#_cursor Exceptionr_handle_exception)r operation parametersr)errors rr&z#AsyncAdapt_aiosqlite_cursor.executes  <kk$"2"2"9"9";>Ccyr )r inputsizess r setinputsizesz)AsyncAdapt_aiosqlite_cursor.setinputsizess rc#xK|jr*|jj|jr)yywr rpopleftr"s r__iter__z$AsyncAdapt_aiosqlite_cursor.__iter__s)jj**$$& &jjs5::cP|jr|jjSyr r7r"s rfetchonez$AsyncAdapt_aiosqlite_cursor.fetchones ::::%%' 'rc| |j}|j}tt|t |Dcgc]}|j c}Scc}wr )rrrangeminlenr8)rsizerr_s r fetchmanyz%AsyncAdapt_aiosqlite_cursor.fetchmanysI <>>D ZZ&+Cc"g,>&?@&? &?@@@sAcdt|j}|jj|Sr )listrr!)rretvals rr(z$AsyncAdapt_aiosqlite_cursor.fetchalls%djj!  rr )__name__ __module__ __qualname__ __slots__r'rr#r&r0r5r9r;rCr(r3rrrrvs> IK<6 < ' Arrc@eZdZdZdZfdZdZdZddZdZ xZ S) AsyncAdapt_aiosqlite_ss_cursorr)Tc2t||i|d|_yr )superrr))rargkw __class__s rrz'AsyncAdapt_aiosqlite_ss_cursor.__init__s #$$ rc~|j1|j|jjd|_yyr )r)rr#r"s rr#z$AsyncAdapt_aiosqlite_ss_cursor.closes1 << # KK **, -DL $rcT|j|jjSr )rr)r;r"s rr;z'AsyncAdapt_aiosqlite_ss_cursor.fetchone{{4<<00233rct| |j}|j|jj|S)N)r@)rrr)rC)rr@s rrCz(AsyncAdapt_aiosqlite_ss_cursor.fetchmanys1 <>>D{{4<<11t1<==rcT|j|jjSr )rr)r(r"s rr(z'AsyncAdapt_aiosqlite_ss_cursor.fetchallrTrr ) rGrHrIrJr'rr#r;rCr( __classcell__rQs@rrLrLs(IK 4> 4rrLceZdZeeZdZdZedZ e jdZ dZ d dZ dZ dZd Zd Zd Zy )AsyncAdapt_aiosqlite_connection)dbapic ||_||_yr )r[r)rr[ connections rrz(AsyncAdapt_aiosqlite_connection.__init__s %rc.|jjSr )risolation_levelr"s rr_z/AsyncAdapt_aiosqlite_connection.isolation_levels///rcNd}t||jj|}tjj }|jj j||f |j|S#t$r}|j|Yd}~yd}~wwxYw)Nc||_yr )r_)r]values rset_isoz@AsyncAdapt_aiosqlite_connection.isolation_level..set_isos ).J &r) rr_connasyncioget_event_loop create_future_tx put_nowaitrr*r+)rrbrcfunctionfuturer.s rr_z/AsyncAdapt_aiosqlite_connection.isolation_levels /7D$4$4$:$:EB'')779 ''(:; *;;v& & *  " "5 ) ) *s/B B$ BB$c |j|jj|i|y#t$r}|j |Yd}~yd}~wwxYwr )rrcreate_functionr*r+)rargsrPr.s rrmz/AsyncAdapt_aiosqlite_connection.create_functionsM * KK8((88$E"E F *  " "5 ) ) *s+. AA  Ac2|r t|St|Sr )rLr)rr's rr%z&AsyncAdapt_aiosqlite_connection.cursors 1$7 7.t4 4rcX|j|jj|i|Sr )rrr&)rrnrPs rr&z'AsyncAdapt_aiosqlite_connection.executes*{{34++33T@R@AArc |j|jjy#t$r}|j |Yd}~yd}~wwxYwr )rrrollbackr*r+rr.s rrrz(AsyncAdapt_aiosqlite_connection.rollbacksC * KK((113 4 *  " "5 ) ) *), AA  Ac |j|jjy#t$r}|j |Yd}~yd}~wwxYwr )rrcommitr*r+rss rrvz&AsyncAdapt_aiosqlite_connection.commit$sC * KK((//1 2 *  " "5 ) ) *rtc |j|jjy#t$rYyt$r}|j |Yd}~yd}~wwxYwr )rrr# ValueErrorr*r+rss rr#z%AsyncAdapt_aiosqlite_connection.close*sP * KK((..0 1   *  " "5 ) ) *s), AAAAct|tr8|jddk(r&|jjj d||)Nrno active connection) isinstancerxrnr[sqliteOperationalErrorrss rr+z1AsyncAdapt_aiosqlite_connection._handle_exception:sG uj ) 1 !77**##44& KrN)F)rGrHrI staticmethodr rrJrpropertyr_setterrmr%r&rrrvr#r+r3rrrZrZsh * %FI&00**&* 5 B* * * rrZc eZdZdZeeZy)'AsyncAdaptFallback_aiosqlite_connectionr3N)rGrHrIrJr~r rr3rrrrFsI . )FrrceZdZdZdZdZy)AsyncAdapt_aiosqlite_dbapicN||_||_d|_|jy)Nqmark) aiosqliter| paramstyle_init_dbapi_attributes)rrr|s rrz#AsyncAdapt_aiosqlite_dbapi.__init__Ms#" ! ##%rc dD]#}t||t|j|%dD]#}t||t|j|%dD]#}t||t|j|%y)N) DatabaseErrorErrorIntegrityErrorNotSupportedErrorr}ProgrammingErrorsqlite_versionsqlite_version_info)PARSE_COLNAMESPARSE_DECLTYPES)Binary)setattrgetattrrr|)rnames rrz1AsyncAdapt_aiosqlite_dbapi._init_dbapi_attributesSsm  D D$ = >  :D D$ T : ;: D D$ T : ; rc$|jdd}|jdd}|r ||i|}n#|jj|i|}d|_t j |rt |t|St|t|S)Nasync_fallbackFasync_creator_fnT) poprconnectdaemonr asboolrr rZr )rrOrPr creator_fnr]s rrz"AsyncAdapt_aiosqlite_dbapi.connectfs 0%8VV.5 #S/B/J///;;J $J  ;;~ &:z*  3:& rN)rGrHrIrrrr3rrrrLs& <&rrceZdZdZy) SQLiteExecutionContext_aiosqlitec:|jjdS)NT)r')_dbapi_connectionr%r"s rcreate_server_side_cursorz:SQLiteExecutionContext_aiosqlite.create_server_side_cursor~s%%,,,>>rN)rGrHrIrr3rrrr}s?rrcXeZdZdZdZdZdZeZe dZ e dZ fdZ dZ xZS)SQLiteDialect_aiosqliterTc>ttdtdS)Nrsqlite3)r __import__)clss r import_dbapiz$SQLiteDialect_aiosqlite.import_dbapis) { #Z %:  rcd|j|rtjStjSr )_is_url_file_dbr AsyncAdaptedQueuePool StaticPool)rurls rget_pool_classz&SQLiteDialect_aiosqlite.get_pool_classs&   s #-- -?? "rct||jjrdt|vryt||||S)NrzT)r{r[r}strrN is_disconnect)rer]r%rQs rrz%SQLiteDialect_aiosqlite.is_disconnects=  tzz** $A.w$Q F;;rc|jSr )r)rr]s rget_driver_connectionz-SQLiteDialect_aiosqlite.get_driver_connections%%%r)rGrHrIdriversupports_statement_cacheis_asyncsupports_server_side_cursorsrexecution_ctx_cls classmethodrrrrrWrXs@rrrsO F#H#' 8  ## <&rr)__doc__re collectionsr functoolsrbaserpysqliterr r enginer util.concurrencyr r rrLrZrrrrdialectr3rrrs]~(,'.*ZZz4%@48T&7Tn*.M* ..b?'=? &4 &F "r