dblite  1.3.0
Simple query interface for SQL databases
api.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 """
3 Simple convenience wrapper for database connections and queries.
4 
5 Provides shorthand functions for operating on a single database connection,
6 and similar interface to multiple databases via returned Database and Transaction objects.
7 
8 ------------------------------------------------------------------------------
9 This file is part of dblite - simple query interface for SQL databases.
10 Released under the MIT License.
11 
12 @author Erki Suurjaak
13 @created 05.03.2014
14 @modified 24.03.2023
15 ------------------------------------------------------------------------------
16 """
17 import collections
18 import inspect
19 import logging
20 
21 from . import util
22 
23 logger = logging.getLogger(__name__)
24 
25 
26 def init(opts=None, engine=None, **kwargs):
27  """
28  Returns a Database object.
29 
30  If opts is `None`, returns the default database - the very first created.
31  Module level functions use the default database.
32 
33  @param opts database connection options, engine-specific;
34  SQLite takes a file path or path-like object or `":memory:"`,
35  Postgres takes a Postgres URI scheme like `"postgresql://user@localhost/mydb"`
36  or a Postgres keyword=value format string like
37  `"host=localhost username=user dbname=mydb"`
38  or a dictionary of connection options like `dict(host="localhost", dbname=..)`
39  @param engine database engine if not auto-detecting from connection options,
40  `"sqlite"` for SQLite3 and `"postgres"` for PostgreSQL (case-insensitive)
41  @param kwargs additional arguments given to engine constructor,
42  e.g. `detect_types=sqlite3.PARSE_COLNAMES` for SQLite,
43  or `minconn=1, maxconn=4` for Postgres connection pool
44  """
45  return Engines.factory(opts, engine, **kwargs)
46 
47 
48 
49 def fetchall(table, cols="*", where=(), group=(), order=(), limit=(), **kwargs):
50  """
51  Convenience wrapper for database SELECT and fetch all.
52  Arguments have the same meaning as in select().
53  """
54  return init().fetchall(table, cols, where, group, order, limit, **kwargs)
55 
56 
57 def fetchone(table, cols="*", where=(), group=(), order=(), limit=(), **kwargs):
58  """
59  Convenience wrapper for database SELECT and fetch one.
60  Arguments have the same meaning as in select().
61  """
62  return init().fetchone(table, cols, where, group, order, limit, **kwargs)
63 
64 
65 def insert(table, values=(), **kwargs):
66  """
67  Convenience wrapper for database INSERT, returns inserted row ID.
68  Keyword arguments are added to VALUES.
69  `table` argument has the same meaning as in select().
70  Column names can be data-class properies as in select().
71 
72  @param values column values to insert, as dict or a sequence of key-value tuples
73  or a data object
74  """
75  return init().insert(table, values, **kwargs)
76 
77 
78 def insertmany(table, rows=(), **kwargs):
79  """
80  Convenience wrapper for database multiple INSERTs, returns list of inserted row IDs.
81  Keyword arguments are added to VALUES of every single row, overriding individual row values.
82  `table` argument has the same meaning as in select().
83  Column names can be data-class properies as in select().
84 
85  @param rows list of row values to insert, as list of dicts
86  or sequences of key-value tuples or data objects
87  """
88  return init().insertmany(table, rows, **kwargs)
89 
90 
91 def select(table, cols="*", where=(), group=(), order=(), limit=(), **kwargs):
92  """
93  Convenience wrapper for database SELECT, returns database cursor.
94 
95  Column names in `where/cols/group/order` arguments can be data-class properties,
96  like `order=MyClass.my_attribute`.
97 
98  @param table table/view name or expression to select from,
99  or a data class with `__name__` used for table name
100  @param where columns or expressions to select by, as dict or a sequence
101  of key-value tuples or a data object; value can specify operator
102  e.g. `{"mycolumn": ("IN", [1, 2, 3])}`
103  @param cols columns to select if not all, as string or a sequence of stringables
104  or a dict with stringable keys
105  @param group columns to GROUP BY, as string or a sequence of stringables
106  or a dict with stringable keys
107  @param order columns to ORDER BY, as string, a sequence of stringables,
108  or a combination of column names and direction flags,
109  or a dict with column name keys and direction flag values.
110  Direction flag can be string like `"ASC"`,
111  or truthy/falsy for ascending/descending.
112  @param limit LIMIT .. OFFSET.. values, as integer or a sequence of integers;
113  None or -1 disables LIMIT or OFFSET
114  @param kwargs additional arguments added to WHERE clause
115  """
116  return init().select(table, cols, where, group, order, limit, **kwargs)
117 
118 
119 def update(table, values, where=(), **kwargs):
120  """
121  Convenience wrapper for database UPDATE, returns affected row count.
122  Arguments have the same meaning as in select().
123  Column names can be data-class properies as in select().
124 
125  @param values column values to set, as dict or a sequence of key-value tuples
126  or a data object
127  """
128  return init().update(table, values, where, **kwargs)
129 
130 
131 def delete(table, where=(), **kwargs):
132  """
133  Convenience wrapper for database DELETE, returns affected row count.
134  Arguments have the same meaning as in select().
135  """
136  return init().delete(table, where, **kwargs)
137 
138 
139 def execute(sql, args=()):
140  """
141  Executes the SQL statement and returns database cursor.
142 
143  @param sql SQL statement to execute, with engine-specific parameter bindings, if any
144  @param args query parameters, as tuple or dictionary
145  """
146  return init().execute(sql, args)
147 
148 
149 def executemany(sql, args):
150  """
151  Executes the SQL statement against all parameter sequences.
152 
153  @param sql SQL statement to execute, with engine-specific parameter bindings
154  @param args iterable of query parameters, as dictionaries for named placeholders
155  or sequences for positional placeholders
156  """
157  return init().executemany(sql, args)
158 
159 
160 def executescript(sql):
161  """
162  Executes the SQL as script of any number of statements.
163 
164  Note that in SQLite, the statements are executed outside of transaction,
165  and any pending transaction will be committed first.
166 
167  @param sql script with one or more SQL statements
168  """
169  return init().executescript(sql)
170 
171 
172 def close(commit=None):
173  """
174  Closes the default database connection, if any.
175 
176  @param commit `True` for explicit commit on open transactions,
177  `False` for explicit rollback on open transactions,
178  `None` defaults to `commit` flag from transaction creations
179  """
180  init().close(commit)
181 
182 
183 def transaction(commit=True, exclusive=None, **kwargs):
184  """
185  Returns a transaction context manager.
186 
187  Context is breakable by raising Rollback.
188 
189  Note that parameter `exclusive` defaults to `True` when using SQLite.
190 
191  @param commit whether transaction commits automatically at exiting with-block
192  @param exclusive whether entering a with-block is exclusive over other
193  Transaction instances on this Database;
194  `None` stands for engine default
195  @param kwargs engine-specific arguments, like `schema="other", lazy=True` for Postgres
196  """
197  return init().transaction(commit, exclusive, **kwargs)
198 
199 
200 def register_adapter(transformer, typeclasses, engine=None):
201  """
202  Registers function to auto-adapt given Python types to database types in query parameters.
203 
204  Registration is global per engine.
205 
206  @param transformer function(Python value) returning adapted value
207  @param typeclasses one or more Python classes to adapt
208  @param engine database engine to adapt for, defaults to first initialized
209  """
210  if not isinstance(typeclasses, (list, set, tuple)): typeclasses = [typeclasses]
211  Engines.get(engine).register_adapter(transformer, typeclasses)
212 
213 
214 def register_converter(transformer, typenames, engine=None):
215  """
216  Registers function to auto-convert given database types to Python in query results.
217 
218  Registration is global per engine.
219 
220  @param transformer function(raw database value) returning Python value
221  @param typenames one or more database column types to adapt
222  @param engine database engine to convert for, defaults to first initialized
223  """
224  if isinstance(typenames, str): typenames = [typenames]
225  Engines.get(engine).register_converter(transformer, typenames)
226 
227 
228 def register_row_factory(row_factory, engine=None):
229  """
230  Registers function to produce query results as custom type.
231 
232  Registration is global per engine; affects future connections and the current default database.
233 
234  @param row_factory function(cursor, row tuple) returning row as desired type
235  or `None` to reset to default. `cursor.description` is a sequence of
236  7-element tuples, as `(column name, ..engine-specific elements..)`.
237  @param engine database engine to register for, defaults to first initialized
238  """
239  Engines.register_row_factory(row_factory, engine)
240 
241 
242 
243 class Queryable(object):
244  """Abstract base for Database and Transaction."""
245 
246 
247  ENGINE = None
248 
249 
250  def fetchall(self, table, cols="*", where=(), group=(), order=(), limit=(), **kwargs):
251  """
252  Convenience wrapper for database SELECT and fetch all.
253  Keyword arguments are added to WHERE.
254  """
255  return list(self.select(table, cols, where, group, order, limit, **kwargs))
256 
257 
258  def fetchone(self, table, cols="*", where=(), group=(), order=(), limit=(), **kwargs):
259  """
260  Convenience wrapper for database SELECT and fetch one.
261  Keyword arguments are added to WHERE.
262  """
263  limit = 1 if not limit and limit != 0 else limit
264  return next(self.select(table, cols, where, group, order, limit, **kwargs), None)
265 
266 
267  def insert(self, table, values=(), **kwargs):
268  """
269  Convenience wrapper for database INSERT, returns inserted row ID.
270  Keyword arguments are added to VALUES.
271  """
272  raise NotImplementedError()
273 
274 
275  def insertmany(self, table, rows=(), **kwargs):
276  """
277  Convenience wrapper for database multiple INSERTs, returns list of inserted row IDs.
278  Keyword arguments are added to VALUES of every single row, overriding individual row values.
279  """
280  return init().insertmany(table, rows, **kwargs)
281 
282 
283  def select(self, table, cols="*", where=(), group=(), order=(), limit=(), **kwargs):
284  """
285  Convenience wrapper for database SELECT, returns database cursor.
286  Keyword arguments are added to WHERE.
287  """
288  sql, args = self.makeSQL("SELECT", table, cols, where, group, order, limit, kwargs=kwargs)
289  cursor = self.execute(sql, args)
290  return TypeCursor(cursor, table) if inspect.isclass(table) else cursor
291 
292 
293  def update(self, table, values, where=(), **kwargs):
294  """
295  Convenience wrapper for database UPDATE, returns affected row count.
296  Keyword arguments are added to WHERE.
297  """
298  sql, args = self.makeSQL("UPDATE", table, values=values, where=where, kwargs=kwargs)
299  return self.execute(sql, args).rowcount
300 
301 
302  def delete(self, table, where=(), **kwargs):
303  """
304  Convenience wrapper for database DELETE, returns affected row count.
305  Keyword arguments are added to WHERE.
306  """
307  sql, args = self.makeSQL("DELETE", table, where=where, kwargs=kwargs)
308  return self.execute(sql, args).rowcount
309 
310 
311  def execute(self, sql, args=()):
312  """
313  Executes the SQL statement and returns database cursor.
314 
315  @param sql SQL statement to execute, with engine-specific parameter bindings, if any
316  @param args query parameters, as tuple or dictionary
317  """
318  raise NotImplementedError()
319 
320 
321  def executemany(self, sql, args):
322  """
323  Executes the SQL statement against all parameter sequences
324 
325  @param sql SQL statement to execute, with engine-specific parameter bindings
326  @param args iterable of query parameters, as dictionaries for named placeholders
327  or sequences for positional placeholders
328  """
329  raise NotImplementedError()
330 
331 
332  def executescript(self, sql):
333  """
334  Executes the SQL as script of any number of statements.
335 
336  Note that in SQLite, the statements are executed outside of transaction,
337  and any pending transaction will be committed first.
338 
339  @param sql script with one or more SQL statements
340  """
341  raise NotImplementedError()
342 
343 
344  def makeSQL(self, action, table, cols="*", where=(), group=(), order=(), limit=(), values=(),
345  kwargs=None):
346  """Returns (SQL statement string, parameter dict)."""
347  raise NotImplementedError()
348 
349 
350  @property
351  def closed(self):
352  """Whether currently not open."""
353  raise NotImplementedError()
354 
355 
356  @property
357  def cursor(self):
358  """Database engine cursor object, or `None` if closed."""
359  raise NotImplementedError()
360 
361 
362  @classmethod
363  def quote(cls, value, force=False):
364  """
365  Returns identifier in quotes and proper-escaped for queries,
366  if value needs quoting (has non-alphanumerics, starts with number, or is reserved).
367 
368  @param value the value to quote, returned as-is if not string
369  @param force whether to quote value even if not required
370  """
371  raise NotImplementedError()
372 
373 
374 
375 class Database(Queryable):
376  """
377  Database instance. Usable as an auto-closing context manager.
378 
379  Queries directly on the Database object use autocommit mode.
380 
381  Note that the database connection is not opened immediately on construction.
382  """
383 
384  def transaction(self, commit=True, exclusive=None, **kwargs):
385  """
386  Returns a transaction context manager.
387 
388  Context is breakable by raising Rollback.
389 
390  Note that parameter `exclusive` defaults to `True` when using SQLite.
391 
392  @param commit whether transaction autocommits at exiting with-block
393  @param exclusive whether entering a with-block is exclusive over other
394  Transaction instances on this Database;
395  `None` stands for engine default
396  @param kwargs engine-specific arguments, like `schema="other", lazy=True` for Postgres
397  """
398  raise NotImplementedError()
399 
400  def __enter__(self):
401  """Context manager entry, opens database if not already open, returns Database object."""
402  raise NotImplementedError()
403 
404  def __exit__(self, exc_type, exc_val, exc_trace):
405  """Context manager exit, closes database and any pending transactions if open."""
406  raise NotImplementedError()
407 
408  def __del__(self):
409  """Closes the database, if open."""
410  self.close()
411 
412  def open(self):
413  """Opens database connection if not already open."""
414  raise NotImplementedError()
415 
416  def close(self, commit=None):
417  """
418  Closes the database and any pending transactions, if open.
419 
420  @param commit `True` for explicit commit on open transactions,
421  `False` for explicit rollback on open transactions,
422  `None` defaults to `commit` flag from transaction creations
423  """
424  raise NotImplementedError()
425 
426  @property
427  def row_factory(self):
428  """The custom row factory, if any, as `function(cursor, row tuple)`."""
429  raise NotImplementedError()
430 
431  @row_factory.setter
432  def row_factory(self, row_factory):
433  """
434  Sets custom row factory, as `function(cursor, row tuple)`, or `None` to reset to default.
435 
436  `cursor.description` is a sequence of 7-element tuples,
437  first element being column name and the rest engine-specific.
438 
439  Overrides globally registered row factory, if any.
440  """
441  raise NotImplementedError()
442 
443 
444 class Transaction(Queryable):
445  """
446  Transaction context manager, breakable by raising Rollback.
447 
448  Note that in SQLite, a single connection has one shared transaction state,
449  so it is highly recommended to use exclusive Transaction instances for any action queries,
450  as concurrent transactions can interfere with one another otherwise.
451  """
452 
453  def __init__(self, db, commit=True, exclusive=False, **kwargs):
454  """
455  Constructs a new transaction.
456 
457  Note that parameter `exclusive` defaults to `True` when using SQLite.
458 
459  @param db Database instance
460  @param commit whether transaction commits automatically at exiting with-block
461  @param exclusive whether entering a with-block is exclusive
462  over other Transaction instances on this Database
463  @param kwargs engine-specific arguments, like `schema="other", lazy=True` for Postgres
464  """
465  raise NotImplementedError()
466 
467  def __enter__(self):
468  """Context manager entry, returns Transaction object."""
469  raise NotImplementedError()
470 
471  def __exit__(self, exc_type, exc_val, exc_trace):
472  """Context manager exit, propagates raised errors except Rollback."""
473  raise NotImplementedError()
474 
475  def __del__(self):
476  """Closes the transaction, if open."""
477  self.close()
478 
479  def close(self, commit=None):
480  """
481  Closes the transaction, performing commit or rollback as specified.
482  Required if not using transaction as context manager in a with-block.
483 
484  @param commit `True` for explicit commit, `False` for explicit rollback,
485  `None` defaults to `commit` flag from creation
486  """
487  raise NotImplementedError()
488 
489  def commit(self):
490  """Commits pending actions, if any."""
491  raise NotImplementedError()
492 
493  def rollback(self):
494  """Rolls back pending actions, if any."""
495  raise NotImplementedError()
496 
497  @property
498  def database(self):
499  """Returns transaction Database instance."""
500  raise NotImplementedError()
501 
502 
503 class Rollback(Exception):
504  """
505  Raising in transaction context manager will roll back the transaction
506  and exit the context manager cleanly, without rising further.
507  """
508  pass
509 
510 
511 
512 # ---------------------------------- detail ----------------------------------
513 # \cond HIDDENSYMBOLS
514 class Engines(object):
515  """Database engine broker."""
516 
517 
518  MODULES = None
519 
520 
521  DATABASES = collections.OrderedDict()
522 
523  @classmethod
524  def factory(cls, opts, engine=None, **kwargs):
525  """
526  Returns an opened Database, the first created if opts is `None`.
527 
528  @param opts database connection options, engine-specific;
529  SQLite takes a file path or path-like object or `":memory:"`,
530  Postgres takes a Postgres URI scheme
531  like `"postgresql://user@localhost/mydb"`
532  or a Postgres keyword=value format
533  like `"host=localhost username=user dbname=mydb"`
534  or a dictionary of connection options like `dict(host="localhost", ..)`
535  @param engine database engine if not auto-detecting from connection options,
536  "sqlite" for SQLite3 and "postgres" for PostgreSQL (case-insensitive)
537  @param kwargs additional arguments given to engine constructor,
538  e.g. `detect_types=sqlite3.PARSE_COLNAMES` for SQLite,
539  or `minconn=1, maxconn=4` for Postgres connection pool
540  """
541  cls.populate()
542  engine = engine.lower() if engine else None
543  if opts is None and engine is None: # Return first database, or raise
544  engine = next(iter(cls.DATABASES))
545  elif opts is not None: # Auto-detect engine from options, or raise
546  engine = next(n for n, m in cls.MODULES.items() if m.autodetect(opts))
547  db = cls.DATABASES[engine] if opts is None else cls.MODULES[engine].Database(opts, **kwargs)
548  cls.DATABASES.setdefault(engine, db)
549  db.open()
550  return db
551 
552  @classmethod
553  def get(cls, engine=None):
554  """Returns engine module, by default the first created."""
555  cls.populate()
556  engine = engine.lower() if engine else next(iter(cls.DATABASES))
557  return cls.MODULES[engine]
558 
559  @classmethod
560  def populate(cls):
561  """Populates Database engines, if not already populated."""
562  if cls.MODULES is None: cls.MODULES = util.load_modules()
563 
564  @classmethod
565  def register_row_factory(cls, row_factory, engine):
566  """Registers row factory for engine, and current engine default database if any."""
567  engine = engine.lower() if engine else next(iter(cls.DATABASES))
568  cls.MODULES[engine].register_row_factory(row_factory)
569  if cls.DATABASES.get(engine): cls.DATABASES[engine].row_factory = row_factory
570 
571 
572 class TypeCursor(object):
573  """Wrapper for database cursor, yielding rows constructed with given callable."""
574 
575  def __init__(self, cursor, callable):
576  """
577  @param cursor database engine cursor instance
578  @param callable function(rowdict) or function(*row values) or function(**rowdict)
579  """
580  self.__cursor = cursor
581  self.__cls = callable
582  self.__logged = False
583  for name, value in inspect.getmembers(cursor):
584  if not hasattr(self, name): # Monkey-patch cursor members to self
585  setattr(self, name, value)
586 
587  def fetchmany(self, size=None):
588  result = []
589  for _ in range(self.__cursor.arraysize if size is None else size):
590  row = next(self.__cursor, None)
591  if row is None: break # for
592  result.append(self.__factory(row))
593  return result
594 
595  def fetchone(self): return next(self, None)
596  def fetchall(self): return list(self)
597  def __iter__(self): return iter(self.__factory(x) for x in self.__cursor)
598  def __next__(self): return self.__factory(next(self.__cursor))
599  def next(self): return self.__factory(next(self.__cursor))
600 
601  def __factory(self, row):
602  """Returns row constructed with callable, or original row if all argument options failed."""
603  result, errors = util.factory(self.__cls, row)
604  if result is row and not self.__logged:
605  logger.warning("Failed to instantiate %s with keywords, posargs, and dictionary. "
606  "Returning dictionary.\n%s", self.__cls, "\n".join(map(repr, errors)))
607  self.__logged = True
608  return result
609 # \endcond
610 
611 
612 __all__ = [
613  "Database", "Rollback", "Transaction",
614  "init", "fetchall", "fetchone", "insert", "insertmany", "select", "update", "delete",
615  "execute", "executemany", "executescript", "close", "transaction",
616  "register_adapter", "register_converter", "register_row_factory",
617 ]
dblite.api.Database.__exit__
def __exit__(self, exc_type, exc_val, exc_trace)
Context manager exit, closes database and any pending transactions if open.
Definition: api.py:401
dblite.api.update
def update(table, values, where=(), **kwargs)
Convenience wrapper for database UPDATE, returns affected row count.
Definition: api.py:123
dblite.api.Queryable.executemany
def executemany(self, sql, args)
Executes the SQL statement against all parameter sequences.
Definition: api.py:321
dblite.api.Transaction.__exit__
def __exit__(self, exc_type, exc_val, exc_trace)
Context manager exit, propagates raised errors except Rollback.
Definition: api.py:470
dblite.api.Transaction.rollback
def rollback(self)
Rolls back pending actions, if any.
Definition: api.py:491
dblite.api.Queryable.fetchone
def fetchone(self, table, cols="*", where=(), group=(), order=(), limit=(), **kwargs)
Convenience wrapper for database SELECT and fetch one.
Definition: api.py:256
dblite.api.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: api.py:367
dblite.api.Queryable.delete
def delete(self, table, where=(), **kwargs)
Convenience wrapper for database DELETE, returns affected row count.
Definition: api.py:300
dblite.api.executescript
def executescript(sql)
Executes the SQL as script of any number of statements.
Definition: api.py:163
dblite.api.Transaction.__enter__
def __enter__(self)
Context manager entry, returns Transaction object.
Definition: api.py:466
dblite.api.insertmany
def insertmany(table, rows=(), **kwargs)
Convenience wrapper for database multiple INSERTs, returns list of inserted row IDs.
Definition: api.py:84
dblite.api.fetchone
def fetchone(table, cols="*", where=(), group=(), order=(), limit=(), **kwargs)
Convenience wrapper for database SELECT and fetch one.
Definition: api.py:60
dblite.api.init
def init(opts=None, engine=None, **kwargs)
Returns a Database object.
Definition: api.py:43
dblite.api.Database.__enter__
def __enter__(self)
Context manager entry, opens database if not already open, returns Database object.
Definition: api.py:397
dblite.api.Rollback
Definition: api.py:507
dblite.api.select
def select(table, cols="*", where=(), group=(), order=(), limit=(), **kwargs)
Convenience wrapper for database SELECT, returns database cursor.
Definition: api.py:112
dblite.api.Queryable.closed
closed
Whether currently not open.
Definition: api.py:345
dblite.api.Database
Database instance.
Definition: api.py:379
dblite.api.Database.open
def open(self)
Opens database connection if not already open.
Definition: api.py:409
Exception
dblite.api.executemany
def executemany(sql, args)
Executes the SQL statement against all parameter sequences.
Definition: api.py:151
dblite.api.execute
def execute(sql, args=())
Executes the SQL statement and returns database cursor.
Definition: api.py:141
dblite.api.Database.transaction
def transaction(self, commit=True, exclusive=None, **kwargs)
Returns a transaction context manager.
Definition: api.py:394
dblite.api.Database.row_factory
row_factory
The custom row factory, if any, as `function(cursor, row tuple)`.
Definition: api.py:424
dblite.api.Queryable.fetchall
def fetchall(self, table, cols="*", where=(), group=(), order=(), limit=(), **kwargs)
Convenience wrapper for database SELECT and fetch all.
Definition: api.py:248
dblite.api.Transaction.__del__
def __del__(self)
Closes the transaction, if open.
Definition: api.py:474
dblite.api.Queryable.cursor
cursor
Database engine cursor object, or `None` if closed.
Definition: api.py:353
dblite.api.Transaction.__init__
def __init__(self, db, commit=True, exclusive=False, **kwargs)
Constructs a new transaction.
Definition: api.py:463
dblite.api.Database.close
def close(self, commit=None)
Closes the database and any pending transactions, if open.
Definition: api.py:419
dblite.api.close
def close(commit=None)
Closes the default database connection, if any.
Definition: api.py:173
dblite.api.Transaction.close
def close(self, commit=None)
Closes the transaction, performing commit or rollback as specified.
Definition: api.py:484
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.api.fetchall
def fetchall(table, cols="*", where=(), group=(), order=(), limit=(), **kwargs)
Convenience wrapper for database SELECT and fetch all.
Definition: api.py:52
dblite.api.transaction
def transaction(commit=True, exclusive=None, **kwargs)
Returns a transaction context manager.
Definition: api.py:190
dblite.api.Queryable.execute
def execute(self, sql, args=())
Executes the SQL statement and returns database cursor.
Definition: api.py:311
dblite.api.Queryable.update
def update(self, table, values, where=(), **kwargs)
Convenience wrapper for database UPDATE, returns affected row count.
Definition: api.py:291
dblite.api.Transaction.commit
def commit(self)
Commits pending actions, if any.
Definition: api.py:487
dblite.api.Queryable.select
def select(self, table, cols="*", where=(), group=(), order=(), limit=(), **kwargs)
Convenience wrapper for database SELECT, returns database cursor.
Definition: api.py:281
dblite.api.register_row_factory
def register_row_factory(row_factory, engine=None)
Registers function to produce query results as custom type.
Definition: api.py:232
dblite.api.Queryable.insert
def insert(self, table, values=(), **kwargs)
Convenience wrapper for database INSERT, returns inserted row ID.
Definition: api.py:265
dblite.api.Transaction.database
database
Returns transaction Database instance.
Definition: api.py:497
dblite.api.Transaction
Transaction context manager, breakable by raising Rollback.
Definition: api.py:450
dblite.api.Queryable.insertmany
def insertmany(self, table, rows=(), **kwargs)
Convenience wrapper for database multiple INSERTs, returns list of inserted row IDs.
Definition: api.py:273
dblite.api.register_adapter
def register_adapter(transformer, typeclasses, engine=None)
Registers function to auto-adapt given Python types to database types in query parameters.
Definition: api.py:203
dblite.api.register_converter
def register_converter(transformer, typenames, engine=None)
Registers function to auto-convert given database types to Python in query results.
Definition: api.py:217
dblite.util.factory
def factory(ctor, data)
Returns object constructed with data dictionary.
Definition: util.py:58
dblite.api.Queryable
Abstract base for Database and Transaction.
Definition: api.py:237
dblite.api.insert
def insert(table, values=(), **kwargs)
Convenience wrapper for database INSERT, returns inserted row ID.
Definition: api.py:72
dblite.api.delete
def delete(table, where=(), **kwargs)
Convenience wrapper for database DELETE, returns affected row count.
Definition: api.py:131
dblite.api.Queryable.executescript
def executescript(self, sql)
Executes the SQL as script of any number of statements.
Definition: api.py:333
dblite.api.Database.__del__
def __del__(self)
Closes the database, if open.
Definition: api.py:405