dblite  1.3.0
Simple query interface for SQL databases
sqlite.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 """
3 Simple convenience wrapper for SQLite.
4 
5 ------------------------------------------------------------------------------
6 This file is part of dblite - simple query interface for SQL databases.
7 Released under the MIT License.
8 
9 @author Erki Suurjaak
10 @created 05.03.2014
11 @modified 26.03.2023
12 ------------------------------------------------------------------------------
13 """
14 import collections
15 import inspect
16 import logging
17 import os
18 import re
19 import sqlite3
20 import sys
21 import threading
22 
23 from six import binary_type, integer_types, string_types, text_type
24 
25 from .. import api, util
26 
27 logger = logging.getLogger(__name__)
28 
29 
30 
31 RESERVED_KEYWORDS = [
32  "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ALWAYS", "ANALYZE", "AND", "AS", "ASC", "ATTACH",
33  "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", "CASE", "CAST", "CHECK", "COLLATE",
34  "COMMIT", "CONSTRAINT", "CREATE", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
35  "DEFAULT", "DEFERRABLE", "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DO", "DROP",
36  "EACH", "ELSE", "END", "ESCAPE", "EXCEPT", "EXISTS", "EXPLAIN", "FOR", "FOREIGN", "FROM",
37  "GENERATED", "GROUP", "HAVING", "IF", "IMMEDIATE", "IN", "INDEX", "INITIALLY", "INSERT",
38  "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", "LIKE", "LIMIT", "MATCH",
39  "NO", "NOT", "NOTHING", "NOTNULL", "NULL", "OF", "ON", "OR", "ORDER", "OVER", "PRAGMA",
40  "PRECEDING", "PRIMARY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", "REINDEX", "RELEASE",
41  "RENAME", "REPLACE", "RESTRICT", "ROLLBACK", "SAVEPOINT", "SELECT", "SET", "TABLE",
42  "TEMPORARY", "THEN", "TIES", "TO", "TRANSACTION", "TRIGGER", "UNBOUNDED", "UNION",
43  "UNIQUE", "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "WHEN", "WHERE", "WITHOUT"
44 ]
45 
46 
48 
49 
50  OPS = ["||", "*", "/", "%", "+", "-", "<<", ">>", "&", "|", "<", "<=", ">",
51  ">=", "=", "==", "!=", "<>", "IS", "IS NOT", "IN", "NOT IN", "LIKE",
52  "GLOB", "MATCH", "REGEXP", "AND", "OR"]
53 
54 
55  ENGINE = "sqlite"
56 
57 
58  def insert(self, table, values=(), **kwargs):
59  """
60  Convenience wrapper for database INSERT, returns inserted row ID.
61  Keyword arguments are added to VALUES.
62  """
63  sql, args = self.makeSQL("INSERT", table, values=values, kwargs=kwargs)
64  return self.execute(sql, args).lastrowid
65 
66 
67  def insertmany(self, table, rows=(), **kwargs):
68  """
69  Convenience wrapper for database multiple INSERTs, returns list of inserted row IDs.
70  Keyword arguments are added to VALUES of every single row, overriding individual row values.
71  """
72 
73  result = []
74  sqlcache = {} # {tuple(col, ): "INSERT .."}
75  commons = {util.nameify(k, parent=table): v for k, v in kwargs.items()}
76  for row in rows:
77  cols, values, valueidx = [], [], {}
78  for k, v in util.keyvalues(row):
79  k = util.nameify(k, parent=table)
80  cols.append(k), values.append((k, v)), valueidx.update({k: len(valueidx)})
81  for k, v in commons.items():
82  if k in valueidx: values[valueidx[k]] = (k, v)
83  else: cols.append(k), values.append((k, v))
84  cols.sort(key=lambda x: x.lower()), values.sort(key=lambda x: x[0].lower())
85  cachekey = tuple(cols)
86 
87  sql = sqlcache.get(cachekey)
88  if not sql:
89  sql, args = self.makeSQL("INSERT", table, values=values)
90  sqlcache[cachekey] = sql
91  else:
92  keys = ["%sI%s" % (re.sub(r"\W+", "_", k), i) for i, (k, _) in enumerate(values)]
93  args = {n: self._cast(k, v) for n, (k, v) in zip(keys, values)}
94  result.append(self.execute(sql, args).lastrowid)
95  return result
96 
97 
98  def makeSQL(self, action, table, cols="*", where=(), group=(), order=(), limit=(), values=(),
99  kwargs=None):
100  """Returns (SQL statement string, parameter dict)."""
101 
102  def parse_members(i, col, op, val):
103  """Returns (col, op, val, argkey)."""
104  col = util.nameify(col, quote, table)
105  key = "%sW%s" % (re.sub(r"\W+", "_", col), i)
106  if "EXPR" == col.upper():
107  # ("EXPR", ("SQL", val))
108  col, op, val, key = val[0], "EXPR", val[1], "EXPRW%s" % i
109  elif col.count("?") == argcount(val):
110  # ("any SQL with ? placeholders", val)
111  op, val, key = "EXPR", listify(val), "EXPRW%s" % i
112  elif isinstance(val, (list, tuple)) and len(val) == 2 \
113  and isinstance(val[0], string_types):
114  tmp = val[0].strip().upper()
115  if tmp in self.OPS:
116  # ("col", ("binary op like >=", val))
117  op, val = tmp, val[1]
118  elif val[0].count("?") == argcount(val[1]):
119  # ("col", ("SQL with ? placeholders", val))
120  col, val, op = "%s = %s" % (col, val[0]), listify(val[1]), "EXPR"
121  return col, op, val, key
122  def argcount(x) : return len(x) if isinstance(x, (list, set, tuple)) else 1
123  def listify(x) : return x if isinstance(x, (list, tuple)) else \
124  list(x) if isinstance(x, set) else [x]
125  def keylistify(x): return x if isinstance(x, (list, tuple)) else \
126  list(x) if isinstance(x, (dict, set)) else [x]
127 
128  action = action.upper()
129  where, group, order, limit, values = (() if x is None else x
130  for x in (where, group, order, limit, values))
131  tablesql = util.nameify(table, quote)
132  cols = ", ".join(util.nameify(x, quote, table) for x in keylistify(cols)) or "*"
133  group = ", ".join(util.nameify(x, quote, table) for x in keylistify(group))
134  where = util.keyvalues(where, quote)
135  order = list(order.items()) if isinstance(order, dict) else listify(order)
136  order = [order] if isinstance(order, (list, tuple)) \
137  and len(order) == 2 and isinstance(order[1], bool) else order
138  limit = [limit] if isinstance(limit, string_types + integer_types) else limit
139  values = util.keyvalues(values, quote)
140  sql = "SELECT %s FROM %s" % (cols, tablesql) if "SELECT" == action else ""
141  sql = "DELETE FROM %s" % (tablesql) if "DELETE" == action else sql
142  sql = "INSERT INTO %s" % (tablesql) if "INSERT" == action else sql
143  sql = "UPDATE %s" % (tablesql) if "UPDATE" == action else sql
144  args = {}
145  if kwargs and action in ("SELECT", "DELETE", "UPDATE"): where += list(kwargs.items())
146  if kwargs and action in ("INSERT", ): values += list(kwargs.items())
147 
148  if "INSERT" == action:
149  keys = ["%sI%s" % (re.sub(r"\W+", "_", self._column(k, table=table)), i)
150  for i, (k, _) in enumerate(values)]
151  args.update((n, self._cast(k, v)) for n, (k, v) in zip(keys, values))
152  cols = ", ".join(self._column(k, sql=True, table=table) for k, _ in values)
153  vals = ", ".join(":%s" % n for n in keys)
154  sql += " (%s) VALUES (%s)" % (cols, vals)
155  if "UPDATE" == action:
156  sql += " SET "
157  for i, (col, val) in enumerate(values):
158  key = "%sU%s" % (re.sub(r"\W+", "_", self._column(col, table=table)), i)
159  sql += (", " if i else "") + \
160  "%s = :%s" % (self._column(col, sql=True, table=table), key)
161  args[key] = self._cast(col, val)
162  if where:
163  sql += " WHERE "
164  for i, clause in enumerate(where):
165  if isinstance(clause, string_types): # "raw SQL with no arguments"
166  clause = (clause, )
167 
168  if len(clause) == 1: # ("raw SQL with no arguments", )
169  col, op, val, key = clause[0], "EXPR", [], None
170  elif len(clause) == 2: # ("col", val) or ("col", ("op" or "expr with ?", val))
171  col, op, val, key = parse_members(i, clause[0], "=", clause[1])
172  else: # ("col", "op" or "expr with ?", val)
173  col, op, val, key = parse_members(i, *clause)
174 
175  if op in ("IN", "NOT IN"):
176  keys = ["%s_%s" % (key, j) for j in range(len(val))]
177  args.update({k: self._cast(col, v) for k, v in zip(keys, val)})
178  sql += (" AND " if i else "") + "%s %s (%s)" % (
179  col, op, ", ".join(":" + x for x in keys))
180  elif "EXPR" == op:
181  for j in range(col.count("?")):
182  col = col.replace("?", ":%s_%s" % (key, j), 1)
183  args["%s_%s" % (key, j)] = self._cast(None, val[j])
184  sql += (" AND " if i else "") + "(%s)" % col
185  elif val is None:
186  op = {"=": "IS", "!=": "IS NOT", "<>": "IS NOT"}.get(op, op)
187  sql += (" AND " if i else "") + "%s %s NULL" % (col, op)
188  else:
189  args[key] = self._cast(col, val)
190  sql += (" AND " if i else "") + "%s %s :%s" % (col, op, key)
191  if group:
192  sql += " GROUP BY " + group
193  if order:
194  sql += " ORDER BY "
195  for i, col in enumerate(order):
196  name = util.nameify(col[0] if isinstance(col, (list, tuple)) else col, quote, table)
197  sort = col[1] if name != col and isinstance(col, (list, tuple)) and len(col) > 1 \
198  else ""
199  if not isinstance(sort, string_types): sort = "" if sort else "DESC"
200  sql += (", " if i else "") + name + (" " if sort else "") + sort
201  if limit:
202  limit = [None if isinstance(v, integer_types) and v < 0 else v for v in limit]
203  for i, (k, v) in enumerate(zip(("limit", "offset"), limit)):
204  if v is None:
205  if i or len(limit) < 2 or not limit[1]: continue # for i, (k, v)
206  v = -1 # LIMIT is required if OFFSET
207  sql += " %s :%s" % (k.upper(), k)
208  args[k] = v
209 
210  logger.log(logging.DEBUG // 2, sql)
211  return sql, args
212 
213 
214  @classmethod
215  def quote(cls, value, force=False):
216  """
217  Returns identifier in quotes and proper-escaped for queries,
218  if value needs quoting (has non-alphanumerics, starts with number, or is reserved).
219 
220  @param value the value to quote, returned as-is if not string
221  @param force whether to quote value even if not required
222  """
223  return quote(value, force)
224 
225 
226  def _cast(self, col, val):
227  """Returns column value cast to correct type for use in sqlite."""
228  return tuple(val) if isinstance(val, set) else val
229 
230 
231  def _column(self, col, sql=False, table=None):
232  """Returns column name from string/property, quoted if object and `sql`."""
233  if inspect.isdatadescriptor(col): col = util.nameify(col, quote if sql else None, table)
234  return col if isinstance(col, string_types) else text_type(col)
235 
236 
237 
239  """
240  Convenience wrapper around sqlite3.Connection.
241 
242  Queries directly on the Database object use autocommit mode.
243  """
244 
245 
246  MUTEX = collections.defaultdict(threading.RLock)
247 
248 
249  ROW_FACTORY = None
250 
251 
252  def __init__(self, opts=":memory:", **kwargs):
253  """
254  Creates a new Database instance for SQLite.
255 
256  @param opts file path or `":memory:"`
257  @param kwargs supported arguments are passed to sqlite3.connect() in open(),
258  like `detect_types=sqlite3.PARSE_COLNAMES`
259  """
260  super(Database, self).__init__()
261  self.connection = None
262  self.path = opts
263  self._kwargs = kwargs
264  self._isolevel = None # Connection isolation level, None is auto-commit
265  rowtype = dict if sys.version_info > (3, ) else collections.OrderedDict
266  self._def_factory = lambda cursor, row: rowtype(sqlite3.Row(cursor, row))
267  self._row_factory = None # None if default, False if explicitly default, or func(cur, row)
268  self._txs = [] # [Transaction, ]
269 
270 
271  def __enter__(self):
272  """Context manager entry, opens database if not already open, returns Database object."""
273  self.open()
274  return self
275 
276 
277  def __exit__(self, exc_type, exc_val, exc_trace):
278  """Context manager exit, closes database and any pending transactions if open."""
279  txs, self._txs[:] = self._txs[:], []
280  for tx in txs: tx.close(commit=None if exc_type is None else False)
281  self.close()
282  return exc_type is None
283 
284 
285  def execute(self, sql, args=()):
286  """
287  Executes the SQL statement and returns sqlite3.Cursor.
288 
289  @param sql SQL statement to execute, with SQLite-specific parameter bindings, if any
290  @param args dictionary for :name placeholders,
291  or a sequence for positional ? placeholders
292  """
293  return self.connection.execute(sql, args)
294 
295 
296  def executemany(self, sql, args):
297  """
298  Executes the SQL statement against all parameter sequences.
299 
300  @param sql SQL statement to execute, with SQLite-specific parameter bindings
301  @param args iterable of query parameters, as dictionaries for :name placeholders
302  or sequences for positional ? placeholders
303  """
304  self.connection.executemany(sql, args)
305 
306 
307  def executescript(self, sql):
308  """
309  Executes the SQL as script of any number of statements.
310 
311  @param sql script with one or more SQL statements
312  """
314 
315 
316  def open(self):
317  """Opens the database connection, if not already open."""
318  if self.connection: return
319  KWS = ("timeout", "detect_types", "isolation_level", "check_same_thread",
320  "factory", "cached_statements", "uri")
321  args = dict(detect_types=sqlite3.PARSE_DECLTYPES,
322  isolation_level=None, check_same_thread=False)
323  args.update({k: v for k, v in self._kwargs.items() if k in KWS})
324  if ":memory:" != self.path and not os.path.exists(self.path):
325  try: os.makedirs(os.path.dirname(self.path))
326  except Exception: pass
327  self.connection = sqlite3.connect(self.path, **args)
328  self._isolevel = self.connection.isolation_level
329  row_factory = self.ROW_FACTORY if self._row_factory is None else self._row_factory
330  if row_factory in (False, None): row_factory = self._def_factory
331  self.connection.row_factory = row_factory
332 
333 
334  def close(self, commit=None):
335  """
336  Closes the database and any pending transactions, if open.
337 
338  @param commit `True` for explicit commit on open transactions,
339  `False` for explicit rollback on open transactions,
340  `None` defaults to `commit` flag from transaction creations
341  """
342  txs, self._txs[:] = self._txs[:], []
343  for tx in txs: tx.close(commit)
344  if self.connection:
345  self.connection.close()
346  self.connection = None
347 
348  @property
349  def closed(self):
350  """Whether database is currently not open."""
351  return not self.connection
352 
353 
354  @property
355  def cursor(self):
356  """Database engine cursor object, or `None` if closed."""
357  return self.connection.cursor() if self.connection else None
358 
359 
360  @property
361  def row_factory(self):
362  """The custom row factory, if any, as `function(cursor, row tuple)`."""
363  return None if self._row_factory in (False, None) else self._row_factory
364 
365 
366  @row_factory.setter
367  def row_factory(self, row_factory):
368  """
369  Sets custom row factory, as `function(cursor, row tuple)`, or `None` to reset to default.
370 
371  `cursor.description` is a sequence of 7-element tuples, as `(column name, None, None, ..)`.
372  """
373  self._row_factory = False if row_factory is None else row_factory
374  if self.connection:
375  factory = self._def_factory if self._row_factory is False else self._row_factory
376  self.connection.row_factory = factory
377 
378 
379  def transaction(self, commit=True, exclusive=True, **kwargs):
380  """
381  Returns a transaction context manager.
382 
383  Context is breakable by raising Rollback.
384 
385  @param commit whether transaction commits automatically at exiting with-block
386  @param exclusive whether entering a with-block is exclusive
387  over other Transaction instances on this Database
388  @param kwargs engine-specific arguments, like `detect_types=sqlite3.PARSE_COLNAMES`
389  """
390  tx = Transaction(self, commit, exclusive, **kwargs)
391  self._txs.append(tx)
392  return tx
393 
394 
395  def _notify(self, tx):
396  """Notifies database of transaction closing."""
397  if tx in self._txs: self._txs.remove(tx)
398  if not self._txs and self.connection: self.connection.isolation_level = self._isolevel
399 
400 
401 
403  """
404  Transaction context manager, breakable by raising Rollback.
405 
406  Note that in SQLite, a single connection has one shared transaction state,
407  so it is highly recommended to use exclusive Transaction instances for any action queries,
408  as concurrent transactions can interfere with one another otherwise.
409  """
410 
411  def __init__(self, db, commit=True, exclusive=True, **__):
412  """
413  Creates a new transaction.
414 
415  @param db Database instance
416  @param commit whether transaction commits automatically at exiting with-block
417  @param exclusive whether entering a with-block is exclusive over other
418  Transaction instances on this Database
419  """
420  self._db = db
421  self._exitcommit = commit
422  self._enterstack = 0 # Number of levels the transaction context is nested at
423  self._exclusive = True if exclusive is None else exclusive
424  self._closed = False
425  self._cursor = None
426 
427  def __enter__(self):
428  """Context manager entry, opens cursor, returns Transaction object."""
429  if self._closed: raise RuntimeError("Transaction already closed")
430 
431  if self._exclusive: Database.MUTEX[self._db].acquire()
432  try: not self._cursor and self._make_cursor()
433  except Exception:
434  if self._exclusive: Database.MUTEX[self._db].release()
435  raise
436  self._enterstack += 1
437  return self
438 
439  def __exit__(self, exc_type, exc_val, exc_trace):
440  """Context manager exit, closes cursor, commits or rolls back as specified on creation."""
441  depth = self._enterstack = self._enterstack - 1
442  try:
443  if self._cursor:
444  self.commit() if self._exitcommit and exc_type is None else self.rollback()
445  return exc_type in (None, api.Rollback) # Do not propagate raised Rollback
446  finally:
447  if depth < 1:
448  self._cursor = None
449  self._closed = True
450  self._db._notify(self)
451  if self._exclusive: Database.MUTEX[self._db].release()
452 
453  def close(self, commit=None):
454  """
455  Closes the transaction, performing commit or rollback as specified.
456 
457  @param commit `True` for final commit, `False` for rollback,
458  `None` for auto-commit, if any
459  """
460  if self._closed:
461  self._db._notify(self)
462  return
463  if commit is False or not commit and not self._exitcommit: self.rollback()
464  elif commit or self._exitcommit: self.commit()
465  self._cursor = None
466  self._closed = True
467  self._db._notify(self)
468 
469  def execute(self, sql, args=()):
470  """
471  Executes the SQL statement and returns sqlite3.Cursor.
472 
473  @param sql SQL statement to execute, with SQLite-specific parameter bindings, if any
474  @param args dictionary for :name placeholders,
475  or a sequence for positional ? placeholders
476  """
477  if self._closed: raise RuntimeError("Transaction already closed")
478  if not self._cursor: self._make_cursor()
479  return self._cursor.execute(sql, args)
480 
481  def executemany(self, sql, args):
482  """
483  Executes the SQL statement against all parameter sequences.
484 
485  @param sql SQL statement to execute, with SQLite-specific parameter bindings
486  @param args iterable of query parameters, as dictionaries for :name placeholders
487  or sequences for positional ? placeholders
488  """
489  if self._closed: raise RuntimeError("Transaction already closed")
490  if not self._cursor: self._make_cursor()
491  self._cursor.executemany(sql, args)
492 
493  def executescript(self, sql):
494  """
495  Executes the SQL as script of any number of statements, outside of transaction.
496 
497  Any pending transaction will be committed first.
498 
499  @param sql script with one or more SQL statements
500  """
501  if self._closed: raise RuntimeError("Transaction already closed")
502  with Database.MUTEX[self._db]:
503  self._reset(commit=True)
504  self._db.executescript(sql)
505 
506  def commit(self):
507  """Commits pending actions, if any."""
508  if not self._cursor: return
509  with Database.MUTEX[self._db]:
510  self._reset(commit=True)
511 
512  def rollback(self):
513  """Rolls back pending actions, if any."""
514  if not self._cursor: return
515  with Database.MUTEX[self._db]:
516  self._reset(commit=False)
517 
518  @property
519  def closed(self):
520  """Whether transaction is currently not open."""
521  return self._closed
522 
523  @property
524  def cursor(self):
525  """Database engine cursor object, or `None` if closed."""
526  if self._closed: return None
527  if not self._cursor: self._make_cursor()
528  return self._cursor
529 
530 
531  @property
532  def database(self):
533  """Returns transaction Database instance."""
534  return self._db
535 
536  def _make_cursor(self):
537  """Opens the transaction cursor."""
538  self._db.connection.isolation_level = "DEFERRED"
539  try: self._cursor = self._db.execute("SAVEPOINT tx%s" % id(self))
540  except Exception:
541  self._db.connection.isolation_level = self._isolevel0
542  raise
543 
544  def _reset(self, commit=False):
545  """Commits or rolls back ongoing transaction, if any, closes cursor, if any."""
546  if getattr(self._db.connection, "in_transaction", True): # Py 3.2+
547  self._db.connection.commit() if commit else self._db.connection.rollback()
548  if self._cursor:
549  self._cursor.close()
550  self._cursor = None
551 
552 
553 
554 def autodetect(opts):
555  """
556  Returns true if input is recognizable as SQLite connection options.
557 
558  @param opts expected as a path string or path-like object
559  """
560  if isinstance(opts, string_types): # E.g. not "postgresql://"
561  return opts.startswith("file:") or not re.match(r"^\w+\:\/\/", opts)
562  elif sys.version_info >= (3, 4):
563  import pathlib
564  return isinstance(opts, pathlib.Path)
565  return False
566 
567 
568 def quote(value, force=False):
569  """
570  Returns identifier in quotes and proper-escaped for queries,
571  if value needs quoting (has non-alphanumerics, starts with number, or is reserved).
572 
573  @param value the value to quote, returned as-is if not string
574  @param force whether to quote value even if not required
575  """
576  if not isinstance(value, string_types):
577  return value
578  RGX_INVALID = r"(^[\W\d])|(?=\W)"
579  result = value.decode() if isinstance(value, binary_type) else value
580  if force or result.upper() in RESERVED_KEYWORDS or re.search(RGX_INVALID, result, re.U):
581  result = u'"%s"' % result.replace('"', '""')
582  return result
583 
584 
585 def register_adapter(transformer, typeclasses):
586  """Registers function to auto-adapt given Python types to SQLite types in query parameters."""
587  for t in typeclasses: sqlite3.register_adapter(t, transformer)
588 
589 
590 def register_converter(transformer, typenames):
591  """Registers function to auto-convert given SQLite types to Python types in query results."""
592  for n in typenames: sqlite3.register_converter(n, transformer)
593 
594 
595 def register_row_factory(row_factory):
596  """Registers custom row factory, as or `None` to reset to default."""
597  Database.ROW_FACTORY = row_factory
598 
599 
600 __all__ = [
601  "RESERVED_KEYWORDS", "Database", "Transaction",
602  "autodetect", "quote", "register_adapter", "register_converter", "register_row_factory",
603 ]
dblite.engines.sqlite.Transaction._make_cursor
def _make_cursor(self)
Opens the transaction cursor.
Definition: sqlite.py:550
dblite.engines.sqlite.Transaction._reset
def _reset(self, commit=False)
Commits or rolls back ongoing transaction, if any, closes cursor, if any.
Definition: sqlite.py:560
dblite.engines.sqlite.Queryable._cast
def _cast(self, col, val)
Returns column value cast to correct type for use in sqlite.
Definition: sqlite.py:229
dblite.engines.sqlite.Transaction.cursor
cursor
Database engine cursor object, or `None` if closed.
Definition: sqlite.py:532
dblite.engines.sqlite.Queryable.OPS
list OPS
Recognized binary operators for makeSQL()
Definition: sqlite.py:50
dblite.engines.sqlite.Database.row_factory
row_factory
The custom row factory, if any, as `function(cursor, row tuple)`.
Definition: sqlite.py:366
dblite.engines.sqlite.Database.closed
closed
Whether database is currently not open.
Definition: sqlite.py:350
dblite.api.Transaction.rollback
def rollback(self)
Rolls back pending actions, if any.
Definition: api.py:491
dblite.engines.sqlite.Database._isolevel
_isolevel
Definition: sqlite.py:267
dblite.engines.sqlite.Database._txs
_txs
Definition: sqlite.py:271
dblite.engines.sqlite.Transaction._exclusive
_exclusive
Definition: sqlite.py:431
dblite.engines.sqlite.Queryable.insertmany
def insertmany(self, table, rows=(), **kwargs)
Convenience wrapper for database multiple INSERTs, returns list of inserted row IDs.
Definition: sqlite.py:71
dblite.engines.sqlite.Database.close
def close(self, commit=None)
Closes the database and any pending transactions, if open.
Definition: sqlite.py:341
dblite.engines.sqlite.Transaction.__exit__
def __exit__(self, exc_type, exc_val, exc_trace)
Context manager exit, closes cursor, commits or rolls back as specified on creation.
Definition: sqlite.py:447
dblite.engines.sqlite.Database.executemany
def executemany(self, sql, args)
Executes the SQL statement against all parameter sequences.
Definition: sqlite.py:304
dblite.engines.sqlite.Transaction._db
_db
Definition: sqlite.py:428
dblite.engines.sqlite.Transaction._cursor
_cursor
Definition: sqlite.py:433
dblite.engines.sqlite.Transaction.rollback
def rollback(self)
Rolls back pending actions, if any.
Definition: sqlite.py:517
dblite.engines.sqlite.Transaction.execute
def execute(self, sql, args=())
Executes the SQL statement and returns sqlite3.Cursor.
Definition: sqlite.py:482
dblite.api.Rollback
Definition: api.py:507
dblite.engines.sqlite.Queryable.quote
def quote(cls, value, force=False)
Returns identifier in quotes and proper-escaped for queries, if value needs quoting (has non-alphanum...
Definition: sqlite.py:222
dblite.engines.sqlite.Database
Convenience wrapper around sqlite3.Connection.
Definition: sqlite.py:247
dblite.api.Database
Database instance.
Definition: api.py:379
dblite.engines.sqlite.autodetect
def autodetect(opts)
Returns true if input is recognizable as SQLite connection options.
Definition: sqlite.py:574
dblite.api.Database.open
def open(self)
Opens database connection if not already open.
Definition: api.py:409
dblite.engines.sqlite.Transaction.database
database
Returns transaction Database instance.
Definition: sqlite.py:542
dblite.engines.sqlite.Database.cursor
cursor
Database engine cursor object, or `None` if closed.
Definition: sqlite.py:358
dblite.engines.sqlite.Transaction.__enter__
def __enter__(self)
Context manager entry, opens cursor, returns Transaction object.
Definition: sqlite.py:435
dblite.engines.sqlite.Database.ROW_FACTORY
ROW_FACTORY
Registered row factory.
Definition: sqlite.py:253
dblite.engines.sqlite.Database.__enter__
def __enter__(self)
Context manager entry, opens database if not already open, returns Database object.
Definition: sqlite.py:274
dblite.engines.sqlite.register_converter
def register_converter(transformer, typenames)
Registers function to auto-convert given SQLite types to Python types in query results.
Definition: sqlite.py:605
dblite.engines.sqlite.Transaction.close
def close(self, commit=None)
Closes the transaction, performing commit or rollback as specified.
Definition: sqlite.py:466
dblite.engines.sqlite.Transaction
Transaction context manager, breakable by raising Rollback.
Definition: sqlite.py:418
dblite.engines.sqlite.Transaction.executemany
def executemany(self, sql, args)
Executes the SQL statement against all parameter sequences.
Definition: sqlite.py:493
dblite.engines.sqlite.Database.executescript
def executescript(self, sql)
Executes the SQL as script of any number of statements.
Definition: sqlite.py:313
dblite.engines.sqlite.Transaction.executescript
def executescript(self, sql)
Executes the SQL as script of any number of statements, outside of transaction.
Definition: sqlite.py:505
dblite.api.Database.close
def close(self, commit=None)
Closes the database and any pending transactions, if open.
Definition: api.py:419
dblite.engines.sqlite.Queryable._column
def _column(self, col, sql=False, table=None)
Returns column name from string/property, quoted if object and `sql`.
Definition: sqlite.py:236
dblite.engines.sqlite.Database.execute
def execute(self, sql, args=())
Executes the SQL statement and returns sqlite3.Cursor.
Definition: sqlite.py:294
dblite.engines.sqlite.Transaction._closed
_closed
Definition: sqlite.py:432
dblite.engines.sqlite.Database._kwargs
_kwargs
Definition: sqlite.py:266
dblite.api.Queryable.makeSQL
def makeSQL(self, action, table, cols="*", where=(), group=(), order=(), limit=(), values=(), kwargs=None)
Returns (SQL statement string, parameter dict).
Definition: api.py:337
dblite.engines.sqlite.Database.path
path
Definition: sqlite.py:265
dblite.engines.sqlite.Database._row_factory
_row_factory
Definition: sqlite.py:270
dblite.engines.sqlite.Database.connection
connection
Definition: sqlite.py:264
dblite.engines.sqlite.Database.__exit__
def __exit__(self, exc_type, exc_val, exc_trace)
Context manager exit, closes database and any pending transactions if open.
Definition: sqlite.py:280
dblite.engines.sqlite.register_row_factory
def register_row_factory(row_factory)
Registers custom row factory, as or `None` to reset to default.
Definition: sqlite.py:610
dblite.api.Queryable.execute
def execute(self, sql, args=())
Executes the SQL statement and returns database cursor.
Definition: api.py:311
dblite.api.Transaction.commit
def commit(self)
Commits pending actions, if any.
Definition: api.py:487
dblite.engines.sqlite.Queryable.makeSQL
def makeSQL(self, action, table, cols="*", where=(), group=(), order=(), limit=(), values=(), kwargs=None)
Returns (SQL statement string, parameter dict).
Definition: sqlite.py:98
dblite.engines.sqlite.Transaction._enterstack
_enterstack
Definition: sqlite.py:430
dblite.api.Transaction
Transaction context manager, breakable by raising Rollback.
Definition: api.py:450
dblite.engines.sqlite.Database.open
def open(self)
Opens the database connection, if not already open.
Definition: sqlite.py:317
dblite.engines.sqlite.register_adapter
def register_adapter(transformer, typeclasses)
Registers function to auto-adapt given Python types to SQLite types in query parameters.
Definition: sqlite.py:600
dblite.engines.sqlite.Database.transaction
def transaction(self, commit=True, exclusive=True, **kwargs)
Returns a transaction context manager.
Definition: sqlite.py:396
dblite.engines.sqlite.Transaction.closed
closed
Whether transaction is currently not open.
Definition: sqlite.py:525
dblite.api.Queryable
Abstract base for Database and Transaction.
Definition: api.py:237
dblite.engines.sqlite.Transaction._exitcommit
_exitcommit
Definition: sqlite.py:429
dblite.engines.sqlite.Queryable
Definition: sqlite.py:47
dblite.engines.sqlite.Queryable.insert
def insert(self, table, values=(), **kwargs)
Convenience wrapper for database INSERT, returns inserted row ID.
Definition: sqlite.py:62
dblite.engines.sqlite.Database._def_factory
_def_factory
Definition: sqlite.py:269
dblite.engines.sqlite.Transaction.commit
def commit(self)
Commits pending actions, if any.
Definition: sqlite.py:511
dblite.engines.sqlite.Database.__init__
def __init__(self, opts=":memory:", **kwargs)
Creates a new Database instance for SQLite.
Definition: sqlite.py:262