25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

608 lines
23KB

  1. # sqlite/pysqlite.py
  2. # Copyright (C) 2005-2021 the SQLAlchemy authors and contributors
  3. # <see AUTHORS file>
  4. #
  5. # This module is part of SQLAlchemy and is released under
  6. # the MIT License: http://www.opensource.org/licenses/mit-license.php
  7. r"""
  8. .. dialect:: sqlite+pysqlite
  9. :name: pysqlite
  10. :dbapi: sqlite3
  11. :connectstring: sqlite+pysqlite:///file_path
  12. :url: http://docs.python.org/library/sqlite3.html
  13. Note that ``pysqlite`` is the same driver as the ``sqlite3``
  14. module included with the Python distribution.
  15. Driver
  16. ------
  17. The ``sqlite3`` Python DBAPI is standard on all modern Python versions;
  18. for cPython and Pypy, no additional installation is necessary.
  19. Connect Strings
  20. ---------------
  21. The file specification for the SQLite database is taken as the "database"
  22. portion of the URL. Note that the format of a SQLAlchemy url is::
  23. driver://user:pass@host/database
  24. This means that the actual filename to be used starts with the characters to
  25. the **right** of the third slash. So connecting to a relative filepath
  26. looks like::
  27. # relative path
  28. e = create_engine('sqlite:///path/to/database.db')
  29. An absolute path, which is denoted by starting with a slash, means you
  30. need **four** slashes::
  31. # absolute path
  32. e = create_engine('sqlite:////path/to/database.db')
  33. To use a Windows path, regular drive specifications and backslashes can be
  34. used. Double backslashes are probably needed::
  35. # absolute path on Windows
  36. e = create_engine('sqlite:///C:\\path\\to\\database.db')
  37. The sqlite ``:memory:`` identifier is the default if no filepath is
  38. present. Specify ``sqlite://`` and nothing else::
  39. # in-memory database
  40. e = create_engine('sqlite://')
  41. .. _pysqlite_uri_connections:
  42. URI Connections
  43. ^^^^^^^^^^^^^^^
  44. Modern versions of SQLite support an alternative system of connecting using a
  45. `driver level URI <https://www.sqlite.org/uri.html>`_, which has the advantage
  46. that additional driver-level arguments can be passed including options such as
  47. "read only". The Python sqlite3 driver supports this mode under modern Python
  48. 3 versions. The SQLAlchemy pysqlite driver supports this mode of use by
  49. specifying "uri=true" in the URL query string. The SQLite-level "URI" is kept
  50. as the "database" portion of the SQLAlchemy url (that is, following a slash)::
  51. e = create_engine("sqlite:///file:path/to/database?mode=ro&uri=true")
  52. .. note:: The "uri=true" parameter must appear in the **query string**
  53. of the URL. It will not currently work as expected if it is only
  54. present in the :paramref:`_sa.create_engine.connect_args`
  55. parameter dictionary.
  56. The logic reconciles the simultaneous presence of SQLAlchemy's query string and
  57. SQLite's query string by separating out the parameters that belong to the
  58. Python sqlite3 driver vs. those that belong to the SQLite URI. This is
  59. achieved through the use of a fixed list of parameters known to be accepted by
  60. the Python side of the driver. For example, to include a URL that indicates
  61. the Python sqlite3 "timeout" and "check_same_thread" parameters, along with the
  62. SQLite "mode" and "nolock" parameters, they can all be passed together on the
  63. query string::
  64. e = create_engine(
  65. "sqlite:///file:path/to/database?"
  66. "check_same_thread=true&timeout=10&mode=ro&nolock=1&uri=true"
  67. )
  68. Above, the pysqlite / sqlite3 DBAPI would be passed arguments as::
  69. sqlite3.connect(
  70. "file:path/to/database?mode=ro&nolock=1",
  71. check_same_thread=True, timeout=10, uri=True
  72. )
  73. Regarding future parameters added to either the Python or native drivers. new
  74. parameter names added to the SQLite URI scheme should be automatically
  75. accommodated by this scheme. New parameter names added to the Python driver
  76. side can be accommodated by specifying them in the
  77. :paramref:`_sa.create_engine.connect_args` dictionary,
  78. until dialect support is
  79. added by SQLAlchemy. For the less likely case that the native SQLite driver
  80. adds a new parameter name that overlaps with one of the existing, known Python
  81. driver parameters (such as "timeout" perhaps), SQLAlchemy's dialect would
  82. require adjustment for the URL scheme to continue to support this.
  83. As is always the case for all SQLAlchemy dialects, the entire "URL" process
  84. can be bypassed in :func:`_sa.create_engine` through the use of the
  85. :paramref:`_sa.create_engine.creator`
  86. parameter which allows for a custom callable
  87. that creates a Python sqlite3 driver level connection directly.
  88. .. versionadded:: 1.3.9
  89. .. seealso::
  90. `Uniform Resource Identifiers <https://www.sqlite.org/uri.html>`_ - in
  91. the SQLite documentation
  92. .. _pysqlite_regexp:
  93. Regular Expression Support
  94. ---------------------------
  95. .. versionadded:: 1.4
  96. Support for the :meth:`_sql.ColumnOperators.regexp_match` operator is provided
  97. using Python's re.search_ function. SQLite itself does not include a working
  98. regular expression operator; instead, it includes a non-implemented placeholder
  99. operator ``REGEXP`` that calls a user-defined function that must be provided.
  100. SQLAlchemy's implementation makes use of the pysqlite create_function_ hook
  101. as follows::
  102. def regexp(a, b):
  103. return re.search(a, b) is not None
  104. sqlite_connection.create_function(
  105. "regexp", 2, regexp,
  106. )
  107. There is currently no support for regular expression flags as a separate
  108. argument, as these are not supported by SQLite's REGEXP operator, however these
  109. may be included inline within the regular expression string. See `Python regular expressions`_ for
  110. details.
  111. .. seealso::
  112. `Python regular expressions`_: Documentation for Python's regular expression syntax.
  113. .. _create_function: https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.create_function
  114. .. _re.search: https://docs.python.org/3/library/re.html#re.search
  115. .. _Python regular expressions: https://docs.python.org/3/library/re.html#re.search
  116. Compatibility with sqlite3 "native" date and datetime types
  117. -----------------------------------------------------------
  118. The pysqlite driver includes the sqlite3.PARSE_DECLTYPES and
  119. sqlite3.PARSE_COLNAMES options, which have the effect of any column
  120. or expression explicitly cast as "date" or "timestamp" will be converted
  121. to a Python date or datetime object. The date and datetime types provided
  122. with the pysqlite dialect are not currently compatible with these options,
  123. since they render the ISO date/datetime including microseconds, which
  124. pysqlite's driver does not. Additionally, SQLAlchemy does not at
  125. this time automatically render the "cast" syntax required for the
  126. freestanding functions "current_timestamp" and "current_date" to return
  127. datetime/date types natively. Unfortunately, pysqlite
  128. does not provide the standard DBAPI types in ``cursor.description``,
  129. leaving SQLAlchemy with no way to detect these types on the fly
  130. without expensive per-row type checks.
  131. Keeping in mind that pysqlite's parsing option is not recommended,
  132. nor should be necessary, for use with SQLAlchemy, usage of PARSE_DECLTYPES
  133. can be forced if one configures "native_datetime=True" on create_engine()::
  134. engine = create_engine('sqlite://',
  135. connect_args={'detect_types':
  136. sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES},
  137. native_datetime=True
  138. )
  139. With this flag enabled, the DATE and TIMESTAMP types (but note - not the
  140. DATETIME or TIME types...confused yet ?) will not perform any bind parameter
  141. or result processing. Execution of "func.current_date()" will return a string.
  142. "func.current_timestamp()" is registered as returning a DATETIME type in
  143. SQLAlchemy, so this function still receives SQLAlchemy-level result
  144. processing.
  145. .. _pysqlite_threading_pooling:
  146. Threading/Pooling Behavior
  147. ---------------------------
  148. Pysqlite's default behavior is to prohibit the usage of a single connection
  149. in more than one thread. This is originally intended to work with older
  150. versions of SQLite that did not support multithreaded operation under
  151. various circumstances. In particular, older SQLite versions
  152. did not allow a ``:memory:`` database to be used in multiple threads
  153. under any circumstances.
  154. Pysqlite does include a now-undocumented flag known as
  155. ``check_same_thread`` which will disable this check, however note that
  156. pysqlite connections are still not safe to use in concurrently in multiple
  157. threads. In particular, any statement execution calls would need to be
  158. externally mutexed, as Pysqlite does not provide for thread-safe propagation
  159. of error messages among other things. So while even ``:memory:`` databases
  160. can be shared among threads in modern SQLite, Pysqlite doesn't provide enough
  161. thread-safety to make this usage worth it.
  162. SQLAlchemy sets up pooling to work with Pysqlite's default behavior:
  163. * When a ``:memory:`` SQLite database is specified, the dialect by default
  164. will use :class:`.SingletonThreadPool`. This pool maintains a single
  165. connection per thread, so that all access to the engine within the current
  166. thread use the same ``:memory:`` database - other threads would access a
  167. different ``:memory:`` database.
  168. * When a file-based database is specified, the dialect will use
  169. :class:`.NullPool` as the source of connections. This pool closes and
  170. discards connections which are returned to the pool immediately. SQLite
  171. file-based connections have extremely low overhead, so pooling is not
  172. necessary. The scheme also prevents a connection from being used again in
  173. a different thread and works best with SQLite's coarse-grained file locking.
  174. Using a Memory Database in Multiple Threads
  175. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  176. To use a ``:memory:`` database in a multithreaded scenario, the same
  177. connection object must be shared among threads, since the database exists
  178. only within the scope of that connection. The
  179. :class:`.StaticPool` implementation will maintain a single connection
  180. globally, and the ``check_same_thread`` flag can be passed to Pysqlite
  181. as ``False``::
  182. from sqlalchemy.pool import StaticPool
  183. engine = create_engine('sqlite://',
  184. connect_args={'check_same_thread':False},
  185. poolclass=StaticPool)
  186. Note that using a ``:memory:`` database in multiple threads requires a recent
  187. version of SQLite.
  188. Using Temporary Tables with SQLite
  189. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  190. Due to the way SQLite deals with temporary tables, if you wish to use a
  191. temporary table in a file-based SQLite database across multiple checkouts
  192. from the connection pool, such as when using an ORM :class:`.Session` where
  193. the temporary table should continue to remain after :meth:`.Session.commit` or
  194. :meth:`.Session.rollback` is called, a pool which maintains a single
  195. connection must be used. Use :class:`.SingletonThreadPool` if the scope is
  196. only needed within the current thread, or :class:`.StaticPool` is scope is
  197. needed within multiple threads for this case::
  198. # maintain the same connection per thread
  199. from sqlalchemy.pool import SingletonThreadPool
  200. engine = create_engine('sqlite:///mydb.db',
  201. poolclass=SingletonThreadPool)
  202. # maintain the same connection across all threads
  203. from sqlalchemy.pool import StaticPool
  204. engine = create_engine('sqlite:///mydb.db',
  205. poolclass=StaticPool)
  206. Note that :class:`.SingletonThreadPool` should be configured for the number
  207. of threads that are to be used; beyond that number, connections will be
  208. closed out in a non deterministic way.
  209. Unicode
  210. -------
  211. The pysqlite driver only returns Python ``unicode`` objects in result sets,
  212. never plain strings, and accommodates ``unicode`` objects within bound
  213. parameter values in all cases. Regardless of the SQLAlchemy string type in
  214. use, string-based result values will by Python ``unicode`` in Python 2.
  215. The :class:`.Unicode` type should still be used to indicate those columns that
  216. require unicode, however, so that non-``unicode`` values passed inadvertently
  217. will emit a warning. Pysqlite will emit an error if a non-``unicode`` string
  218. is passed containing non-ASCII characters.
  219. Dealing with Mixed String / Binary Columns in Python 3
  220. ------------------------------------------------------
  221. The SQLite database is weakly typed, and as such it is possible when using
  222. binary values, which in Python 3 are represented as ``b'some string'``, that a
  223. particular SQLite database can have data values within different rows where
  224. some of them will be returned as a ``b''`` value by the Pysqlite driver, and
  225. others will be returned as Python strings, e.g. ``''`` values. This situation
  226. is not known to occur if the SQLAlchemy :class:`.LargeBinary` datatype is used
  227. consistently, however if a particular SQLite database has data that was
  228. inserted using the Pysqlite driver directly, or when using the SQLAlchemy
  229. :class:`.String` type which was later changed to :class:`.LargeBinary`, the
  230. table will not be consistently readable because SQLAlchemy's
  231. :class:`.LargeBinary` datatype does not handle strings so it has no way of
  232. "encoding" a value that is in string format.
  233. To deal with a SQLite table that has mixed string / binary data in the
  234. same column, use a custom type that will check each row individually::
  235. # note this is Python 3 only
  236. from sqlalchemy import String
  237. from sqlalchemy import TypeDecorator
  238. class MixedBinary(TypeDecorator):
  239. impl = String
  240. cache_ok = True
  241. def process_result_value(self, value, dialect):
  242. if isinstance(value, str):
  243. value = bytes(value, 'utf-8')
  244. elif value is not None:
  245. value = bytes(value)
  246. return value
  247. Then use the above ``MixedBinary`` datatype in the place where
  248. :class:`.LargeBinary` would normally be used.
  249. .. _pysqlite_serializable:
  250. Serializable isolation / Savepoints / Transactional DDL
  251. -------------------------------------------------------
  252. In the section :ref:`sqlite_concurrency`, we refer to the pysqlite
  253. driver's assortment of issues that prevent several features of SQLite
  254. from working correctly. The pysqlite DBAPI driver has several
  255. long-standing bugs which impact the correctness of its transactional
  256. behavior. In its default mode of operation, SQLite features such as
  257. SERIALIZABLE isolation, transactional DDL, and SAVEPOINT support are
  258. non-functional, and in order to use these features, workarounds must
  259. be taken.
  260. The issue is essentially that the driver attempts to second-guess the user's
  261. intent, failing to start transactions and sometimes ending them prematurely, in
  262. an effort to minimize the SQLite databases's file locking behavior, even
  263. though SQLite itself uses "shared" locks for read-only activities.
  264. SQLAlchemy chooses to not alter this behavior by default, as it is the
  265. long-expected behavior of the pysqlite driver; if and when the pysqlite
  266. driver attempts to repair these issues, that will be more of a driver towards
  267. defaults for SQLAlchemy.
  268. The good news is that with a few events, we can implement transactional
  269. support fully, by disabling pysqlite's feature entirely and emitting BEGIN
  270. ourselves. This is achieved using two event listeners::
  271. from sqlalchemy import create_engine, event
  272. engine = create_engine("sqlite:///myfile.db")
  273. @event.listens_for(engine, "connect")
  274. def do_connect(dbapi_connection, connection_record):
  275. # disable pysqlite's emitting of the BEGIN statement entirely.
  276. # also stops it from emitting COMMIT before any DDL.
  277. dbapi_connection.isolation_level = None
  278. @event.listens_for(engine, "begin")
  279. def do_begin(conn):
  280. # emit our own BEGIN
  281. conn.exec_driver_sql("BEGIN")
  282. .. warning:: When using the above recipe, it is advised to not use the
  283. :paramref:`.Connection.execution_options.isolation_level` setting on
  284. :class:`_engine.Connection` and :func:`_sa.create_engine`
  285. with the SQLite driver,
  286. as this function necessarily will also alter the ".isolation_level" setting.
  287. Above, we intercept a new pysqlite connection and disable any transactional
  288. integration. Then, at the point at which SQLAlchemy knows that transaction
  289. scope is to begin, we emit ``"BEGIN"`` ourselves.
  290. When we take control of ``"BEGIN"``, we can also control directly SQLite's
  291. locking modes, introduced at
  292. `BEGIN TRANSACTION <http://sqlite.org/lang_transaction.html>`_,
  293. by adding the desired locking mode to our ``"BEGIN"``::
  294. @event.listens_for(engine, "begin")
  295. def do_begin(conn):
  296. conn.exec_driver_sql("BEGIN EXCLUSIVE")
  297. .. seealso::
  298. `BEGIN TRANSACTION <http://sqlite.org/lang_transaction.html>`_ -
  299. on the SQLite site
  300. `sqlite3 SELECT does not BEGIN a transaction <http://bugs.python.org/issue9924>`_ -
  301. on the Python bug tracker
  302. `sqlite3 module breaks transactions and potentially corrupts data <http://bugs.python.org/issue10740>`_ -
  303. on the Python bug tracker
  304. """ # noqa
  305. import os
  306. import re
  307. from .base import DATE
  308. from .base import DATETIME
  309. from .base import SQLiteDialect
  310. from ... import exc
  311. from ... import pool
  312. from ... import types as sqltypes
  313. from ... import util
  314. class _SQLite_pysqliteTimeStamp(DATETIME):
  315. def bind_processor(self, dialect):
  316. if dialect.native_datetime:
  317. return None
  318. else:
  319. return DATETIME.bind_processor(self, dialect)
  320. def result_processor(self, dialect, coltype):
  321. if dialect.native_datetime:
  322. return None
  323. else:
  324. return DATETIME.result_processor(self, dialect, coltype)
  325. class _SQLite_pysqliteDate(DATE):
  326. def bind_processor(self, dialect):
  327. if dialect.native_datetime:
  328. return None
  329. else:
  330. return DATE.bind_processor(self, dialect)
  331. def result_processor(self, dialect, coltype):
  332. if dialect.native_datetime:
  333. return None
  334. else:
  335. return DATE.result_processor(self, dialect, coltype)
  336. class SQLiteDialect_pysqlite(SQLiteDialect):
  337. default_paramstyle = "qmark"
  338. supports_statement_cache = True
  339. colspecs = util.update_copy(
  340. SQLiteDialect.colspecs,
  341. {
  342. sqltypes.Date: _SQLite_pysqliteDate,
  343. sqltypes.TIMESTAMP: _SQLite_pysqliteTimeStamp,
  344. },
  345. )
  346. if not util.py2k:
  347. description_encoding = None
  348. driver = "pysqlite"
  349. @classmethod
  350. def dbapi(cls):
  351. if util.py2k:
  352. try:
  353. from pysqlite2 import dbapi2 as sqlite
  354. except ImportError:
  355. try:
  356. from sqlite3 import dbapi2 as sqlite
  357. except ImportError as e:
  358. raise e
  359. else:
  360. from sqlite3 import dbapi2 as sqlite
  361. return sqlite
  362. @classmethod
  363. def _is_url_file_db(cls, url):
  364. if (url.database and url.database != ":memory:") and (
  365. url.query.get("mode", None) != "memory"
  366. ):
  367. return True
  368. else:
  369. return False
  370. @classmethod
  371. def get_pool_class(cls, url):
  372. if cls._is_url_file_db(url):
  373. return pool.NullPool
  374. else:
  375. return pool.SingletonThreadPool
  376. def _get_server_version_info(self, connection):
  377. return self.dbapi.sqlite_version_info
  378. def set_isolation_level(self, connection, level):
  379. if hasattr(connection, "connection"):
  380. dbapi_connection = connection.connection
  381. else:
  382. dbapi_connection = connection
  383. if level == "AUTOCOMMIT":
  384. dbapi_connection.isolation_level = None
  385. else:
  386. dbapi_connection.isolation_level = ""
  387. return super(SQLiteDialect_pysqlite, self).set_isolation_level(
  388. connection, level
  389. )
  390. def on_connect(self):
  391. connect = super(SQLiteDialect_pysqlite, self).on_connect()
  392. def regexp(a, b):
  393. if b is None:
  394. return None
  395. return re.search(a, b) is not None
  396. def set_regexp(connection):
  397. if hasattr(connection, "connection"):
  398. dbapi_connection = connection.connection
  399. else:
  400. dbapi_connection = connection
  401. dbapi_connection.create_function(
  402. "regexp",
  403. 2,
  404. regexp,
  405. )
  406. fns = [set_regexp]
  407. if self.isolation_level is not None:
  408. def iso_level(conn):
  409. self.set_isolation_level(conn, self.isolation_level)
  410. fns.append(iso_level)
  411. def connect(conn):
  412. for fn in fns:
  413. fn(conn)
  414. return connect
  415. def create_connect_args(self, url):
  416. if url.username or url.password or url.host or url.port:
  417. raise exc.ArgumentError(
  418. "Invalid SQLite URL: %s\n"
  419. "Valid SQLite URL forms are:\n"
  420. " sqlite:///:memory: (or, sqlite://)\n"
  421. " sqlite:///relative/path/to/file.db\n"
  422. " sqlite:////absolute/path/to/file.db" % (url,)
  423. )
  424. # theoretically, this list can be augmented, at least as far as
  425. # parameter names accepted by sqlite3/pysqlite, using
  426. # inspect.getfullargspec(). for the moment this seems like overkill
  427. # as these parameters don't change very often, and as always,
  428. # parameters passed to connect_args will always go to the
  429. # sqlite3/pysqlite driver.
  430. pysqlite_args = [
  431. ("uri", bool),
  432. ("timeout", float),
  433. ("isolation_level", str),
  434. ("detect_types", int),
  435. ("check_same_thread", bool),
  436. ("cached_statements", int),
  437. ]
  438. opts = url.query
  439. pysqlite_opts = {}
  440. for key, type_ in pysqlite_args:
  441. util.coerce_kw_type(opts, key, type_, dest=pysqlite_opts)
  442. if pysqlite_opts.get("uri", False):
  443. uri_opts = dict(opts)
  444. # here, we are actually separating the parameters that go to
  445. # sqlite3/pysqlite vs. those that go the SQLite URI. What if
  446. # two names conflict? again, this seems to be not the case right
  447. # now, and in the case that new names are added to
  448. # either side which overlap, again the sqlite3/pysqlite parameters
  449. # can be passed through connect_args instead of in the URL.
  450. # If SQLite native URIs add a parameter like "timeout" that
  451. # we already have listed here for the python driver, then we need
  452. # to adjust for that here.
  453. for key, type_ in pysqlite_args:
  454. uri_opts.pop(key, None)
  455. filename = url.database
  456. if uri_opts:
  457. # sorting of keys is for unit test support
  458. filename += "?" + (
  459. "&".join(
  460. "%s=%s" % (key, uri_opts[key])
  461. for key in sorted(uri_opts)
  462. )
  463. )
  464. else:
  465. filename = url.database or ":memory:"
  466. if filename != ":memory:":
  467. filename = os.path.abspath(filename)
  468. return ([filename], pysqlite_opts)
  469. def is_disconnect(self, e, connection, cursor):
  470. return isinstance(
  471. e, self.dbapi.ProgrammingError
  472. ) and "Cannot operate on a closed database." in str(e)
  473. dialect = SQLiteDialect_pysqlite