>>> from tinydb import TinyDB, where
>>> db = TinyDB('/path/to/db.json')
>>> db.insert({'int': 1, 'char': 'a'})
>>> db.search(where('int') == 1)
[{'int': 1, 'char': 'a'}]
Welcome to TinyDB, your tiny, document oriented database optimized for your happiness :) If you’re new here, consider reading the introduction, otherwise feel free to choose one of:
TinyDB is:
In short: If you need a simple database with a clean API that just works without lots of configuration, TinyDB might be the right choice for you.
TinyDB has been tested with Python 2.6, 2.7, 3.2, 3.3 and pypy.
To put it plainly: TinyDB is designed to be tiny and fun to use. If you need advanced features/high performance, TinyDB is the wrong database for you – consider using databases like Buzhug, CodernityDB or MongoDB.
By default, TinyDB stores data as JSON files, so you have to specify the file path:
>>> from tinydb import TinyDB, where
>>> db = TinyDB('/path/to/db.json')
You also can use in-memory JSON to store data:
>>> from tinydb.storages import MemoryStorage
>>> db = TinyDB(storage=MemoryStorage)
As a document-oriented database, TinyDB uses dicts to store data:
>>> db.insert({'int': 1, 'char': 'a'})
>>> db.insert({'int': 1, 'char': 'b'})
>>> db.insert({'int': 1, 'value': 0})
>>> db.insert({'int': 1, 'value': 1})
You can also insert multiple elements at once:
>>> db.insert_multiple([{'int': 1, 'char': 'a'}, {'int': 1, 'char': 'b'}])
>>> db.insert_multiple({'int': 1, 'value': i} for i in range(2))
Hint
Throughout this section, the return values are stripped of the _id key for clarity reasons. So:
[{'int': 1, 'value': 0}]
would actually be some something like:
[{'int': 1, 'value': 0, '_id': 3}]
Getting all data stored:
>>> db.all()
[{'int': 1, 'char': 'a'}, {'int': 1, 'char': 'b'}, {'int': 1, 'value': 0}, {'int': 1, 'value': 1}]
Getting the database size (number of elements stored):
>>> len(db)
4
Search for all elements that have the value key defined:
>>> db.search(where('value'))
[{'int': 1, 'value': 0}, {'int': 1, 'value': 1}]
Search for a specific value:
>>> db.search(where('value') == 1)
[{'int': 1, 'value': 1}]
Count the number of elements matching a query:
>>> db.count(where('int') == 1)
4
Check whether a specific element is in the database:
>>> db.contains(where('int') == 1)
True
>>> db.contains(where('int') == 0)
False
Alternative syntax for db.contains:
>>> if where('value') == 0.5 in db: print 'Found!'
Found!
Warning
Deprecated since version 1.3.0: This syntax will propably be removed soon. Please use the db.contains(...) syntax instead.
Other comparison operators you can use:
Combine two queries with logical and:
>>> db.search((where('int') == 1) & (where('char') == 'b'))
[{'int': 1, 'char': 'b'}]
Combine two queries with logical or:
>>> db.search((where('char') == 'a') | (where('char') == 'b'))
[{'int': 1, 'char': 'a'}, {'int': 1, 'char': 'b'}]
When using & or |, make sure you wrap the conditions on both sides with parentheses or Python will mess up the comparison.
Check against a regex:
>>> db.search(where('char').matches('[aZ]*'))
[{'int': 1, 'char': 'a'}, {'int': 1, 'char': 'b'}]
Use a custom test function:
>>> test_func = lambda c: c == 'a'
>>> db.search(where('char').test(test_func))
[{'char': 'a', 'int': 1}]
Also, if you want to get only one element, you can use:
>>> db.get(where('value'))
{'int': 1, 'value': 0}
Caution
If multiple elements match the query, only one of them will be returned!
You can remove all elements matching a query:
>>> db.remove(where('int') == 1)
>>> len(db)
0
You also can purge all entries:
>>> db.purge()
>>> len(db)
0
You can update elements matching a query. Assuming you have these elements in the database:
>>> db.insert({'int': 1, 'char': 'a'})
>>> db.insert({'int': 1, 'char': 'b'})
>>> db.insert({'int': 1, 'value': 5.0})
Then you can update selected elements like this:
>>> db.update({'int': 2}, where('char') == 'a')
>>> db.all()
[{'int': 2, 'char': 'a'}, {'int': 1, 'char': 'b'}, {'int': 1, 'value': 5.0}]
You can use TinyDB with multiple tables. They behave exactly as described above:
>>> table = db.table('name')
>>> table.insert({'value': True})
>>> table.all()
[{'value': True}]
In addition, you can remove all tables by using:
>>> db.purge_tables()
Hint
When using the operations described above using db, TinyDB actually uses a table named _default.
Middlewares wrap around existing storages allowing you to customize their behaviour.
>>> from tinydb.storages import JSONStorage
>>> from tinydb.middlewares import CachingMiddleware
>>> db = TinyDB('/path/to/db.json', storage=CachingMiddleware(JSONStorage))
TinyDB ships with these middlewares:
Hint
You can nest middlewares:
>>> from tinydb.middlewares import CachingMiddleware, ConcurrencyMiddleware
>>> db = TinyDB('/path/to/db.json', storage=ConcurrencyMiddleware(CachingMiddleware(JSONStorage)))
To write a custom storage, subclass Storage:
The abstract base class for all Storages.
A Storage (de)serializes the current state of the database and stores it in some place (memory, file on disk, ...).
Read the last stored state.
Any kind of deserialization should go here.
Return type: | dict |
---|
Write the current state of the database to the storage.
Any kind of serialization should go here.
Parameters: | data (dict) – The current state of the database. |
---|
To use your custom storage, use:
db = TinyDB(storage=YourStorageClass)
Hint
TinyDB will pass all arguments and keyword arguments (except for storage) to your storage’s __init__.
For example implementations, check out the source of JSONStorage or MemoryStorage.
To write a custom storage, subclass Middleware:
The base class for all Middlewares.
Middlewares hook into the read/write process of TinyDB allowing you to extend the behaviour by adding caching, logging, ...
Your middleware’s __init__ method has to accept exactly one argument which is the class of the “real” storage. It has to be stored as _storage_cls (see CachingMiddleware for an example).
Modify the way TinyDB reads data.
To access the underlying storage’s read method, use self.storage.read.
Modify the way TinyDB writes data.
To access the underlying storage’s read method, use self.storage.read.
To use your middleware, use:
db = TinyDB(storage=YourMiddleware(SomeStorageClass))
For example implementations, check out the source of CachingMiddleware or ConcurrencyMiddleware.
TinyDB serializes all data using the Python JSON module by default. It serializes most basic Python data types very well, but fails serializing classes and stores tuple as list. If you need a better serializer, you can write your own storage, that e.g. uses the more powerful (but also slower) pickle or PyYAML.
TinyDB is NOT designed to be used in environments where performance might be an issue. Although you can improve the TinyDB performance as described below, you should consider using a DB that is optimized for speed like Buzhug or CodernityDB.
The default storage serializes the data using JSON. To improve performance, you can install ujson , an extremely fast JSON implementation. TinyDB will auto-detect and use it if possible.
In addition, you can wrap the storage with the CachingMiddleware which reduces disk I/O.
Contains the database and tables implementation.
Represents a single TinyDB Table.
Equals to bool(table.search(condition))).
Allow the database to be used as a context manager.
Returns: | the table instance |
---|
Try to close the storage after being used as a context manager.
Get access to a table.
Parameters: |
|
---|
Get the total number of elements in the table.
Get all elements stored in the table.
Note: all elements will have an _id key.
Returns: | a list with all elements. |
---|---|
Return type: | list[dict] |
Check wether the database contains an element matching a condition.
Parameters: | cond (Query) – the condition use |
---|
Count the elements matching a condition.
Parameters: | cond (Query) – the condition use |
---|
Search for exactly one element matching a condition.
Note: all elements will have an _id key.
Parameters: | cond (Query) – the condition to check against |
---|---|
Returns: | the element or None |
Return type: | dict or None |
Insert a new element into the table.
Parameters: | element – a dict. Shall not containing the key _id! |
---|
Insert multiple elements into the table.
Parameters: | elements – a list of elements to insert |
---|
Purge the table by removing all elements.
Remove the element matching the condition.
Parameters: | cond (query, int, list) – the condition to check against |
---|
Search for all elements matching a ‘where’ cond.
Note: all elements will have an _id key.
Parameters: | cond (Query) – the condition to check against |
---|---|
Returns: | list of matching elements |
Return type: | list |
Update all elements matching the condition to have a given set of fields.
Parameters: |
|
---|
The main class of TinyDB.
Gives access to the database, provides methods to insert/search/remove and getting tables.
A shorthand for query(...) == ... in db.table(). Intendet to be used in if-clauses (avoiding if len(db.serach(...)):)
>>> if where('field') == 'value' in db:
... print True
See Table.__exit__()
Forward all unknown attribute calls to the underlying standard table.
Create a new instance of TinyDB.
All arguments and keyword arguments will be passed to the underlying storage class (default: JSONStorage).
Get the total number of elements in the DB.
>>> len(db)
0
Purge all tables from the database. CANT BE REVERSED!
Get access to a specific table.
Creates a new table, if it hasn’t been created before, otherwise it returns the cached Table object.
Parameters: | name (str) – The name of the table. |
---|
Contains the querying interface.
Starting with Query you can construct complex queries:
>>> ((where('f1') == 5) & (where('f2') != 2)) | where('s').matches('^\w+$')
(('f1' == 5) and ('f2' != 2)) or ('s' ~= ^\w+$ )
Queries are executed by using the __call__:
>>> q = where('val') == 5
>>> q({'val': 5})
True
>>> q({'val': 1})
False
Provides methods to do tests on dict fields.
Any type of comparison will be called in this class. In addition, it is aliased to where to provide a more intuitive syntax.
When not using any comparison operation, this simply tests for existence of the given key.
Run the test on the element.
Parameters: | element (dict) – The dict that we will run our tests against. |
---|
Test a dict value for equality.
>>> where('f1') == 42
'f1' == 42
Test a dict value for being greater than or equal to another value.
>>> where('f1') >= 42
'f1' >= 42
Test a dict value for being greater than another value.
>>> where('f1') > 42
'f1' > 42
Negates a query.
>>> ~(where('f1') >= 42)
not ('f1' >= 42)
Return type: | tinydb.queries.QueryNot |
---|
Test a dict value for being lower than or equal to another value.
>>> where('f1') <= 42
'f1' <= 42
Test a dict value for being lower than another value.
>>> where('f1') < 42
'f1' < 42
Test a dict value for inequality.
>>> where('f1') != 42
'f1' != 42
Run a regex test against a dict value.
>>> where('f1').matches('^\w+$')
'f1' ~= ^\w+$
Parameters: | regex – The regular expression to pass to re.match |
---|---|
Return type: | QueryRegex |
Run a user-defined test function against a dict value.
>>> def test_func(val):
... return val == 42
...
>>> where('f1').test(test_func)
'f1'.test(<function test_func at 0x029950F0>)
Parameters: | func – The function to run. Has to accept one parameter and return a boolean. |
---|---|
Return type: | QueryCustom |
A mixin providing methods calls & and |.
All queries can be combined with & and |. Thus, we provide a mixin here to prevent repeating this code all the time.
Combines this query and another with logical and.
Example:
>>> (where('f1') == 5) & (where('f2') != 2)
('f1' == 5) and ('f2' != 2)
Return type: | QueryAnd |
---|
Combines this query and another with logical or.
Example:
>>> (where('f1') == 5) | (where('f2') != 2)
('f1' == 5) or ('f2' != 2)
Return type: | QueryOr |
---|
Contains the base class for storages and two implementations.
Contains the base class for middlewares and two implementations.
Add some caching to TinyDB.
This Middleware aims to improve the performance of TinyDB by writing only the last DB state every WRITE_CACHE_SIZE time and reading always from cache.
Flush all unwritten data to disk.
Makes TinyDB working with multithreading.
Uses a lock so write/read operations are virtually atomic.
TinyDB follows the SemVer versioning guidelines. For more information, see semver.org