Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
The lino.utils.dbhash
module¶
This document demonstrates the lino.utils.dbhash
module, which is used in
tested documents.
All code snippets on this page (lines starting with >>>
) are being
tested as part of our development workflow. The following
snippet initializes a demo project to use throughout this page.
>>> from lino_book.projects.min1.startup import *
Usage¶
It sometimes happens that we modify the content of the database of a demo project during a doctest. Such changes remain in the database if we don’t “tidy up”, i.e. restore the database state. And they can cause doctest failures in other documents that are absolutely unrelated except that they use the same demo project. Such failures can be difficult to debug.
The check_virgin()
function is there to warn us when the database is not
“virgin”, i.e. has been modified after pm prep
.
It usually does not print anything, which means that everything is okay. But when the database has been modified it prints a warning message, causing our doctest to fail.
Let’s try it:
>>> dbhash.check_virgin()
Uff! No warning! Now we know that our database is virgin.
Now here is a code snippet that modifies the content of the database by creating a database object and then saving it:
>>> obj = contacts.Person(first_name="Joe")
>>> obj.full_clean()
>>> obj.save()
We now have modified the database, so here is what the check_virgin()
now
says:
>>> dbhash.check_virgin() #docterst: +ELLIPSIS
Database .../lino_book/projects/min1 isn't virgin:
- contacts.Partner: 1 rows added
- contacts.Person: 1 rows added
Database has been restored.
Our instance of lino_xl.lib.contacts.Person
no longer exists in the
database:
>>> contacts.Person.objects.get(pk=obj.pk)
Traceback (most recent call last):
...
lino_xl.lib.contacts.models.Person.DoesNotExist: Person matching query does not exist.
Calling check_virgin()
a second time will be silent again because the
database state has been restored.
>>> dbhash.check_virgin() #docterst: +ELLIPSIS
Limitations¶
The restore is not perfect. For example the value of the next available primary
key of a table does not get restored. That’s whay we cannot rely on the
primary key of temporary database objects being the same. The folllowing test
would pass when running this doctest for the first time after pm prep
,
but it would fail the second time because
>>> print(obj.pk)
183
Another limitation is that dbhash.check_virgin() can’t tidy up in when we also update existing database rows. The dbhash ignores these changes, it considers only the primary keys per model.
Here is how the dbhash looks like. It is a dict with one key for every database model, and the value is a list of the primary keys of every row.
>>> pprint(dbhash.compute_dbhash(), compact=True)
{'contacts.Company': [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111],
'contacts.CompanyType': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16],
'contacts.Partner': [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,
133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
177, 178, 179, 180],
'contacts.Person': [114, 112, 113, 115, 116, 169, 176, 119, 118, 117, 121, 179,
120, 123, 122, 178, 170, 174, 127, 149, 151, 150, 128, 124,
126, 125, 129, 130, 131, 133, 132, 134, 136, 135, 180, 137,
138, 139, 140, 177, 175, 141, 142, 143, 144, 145, 171, 146,
148, 147, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
162, 172, 173, 164, 163, 165, 168, 166, 167],
'contacts.Role': [3, 1, 2],
'contacts.RoleType': [1, 2, 3, 4, 5],
'countries.Country': ['BD', 'BE', 'CD', 'DE', 'EE', 'FR', 'MA', 'NL', 'RU',
'US'],
'countries.Place': [1, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 26, 33, 34, 35, 36, 46, 47, 48, 49,
50, 51, 52, 53, 60, 61, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 80, 2, 4, 25, 27, 28, 29,
30, 31, 32, 37, 38, 39, 40, 41, 42, 43, 44, 45, 56, 62, 59,
54, 55, 57, 58],
'system.SiteConfig': [1],
'users.Authority': [],
'users.User': [3, 2, 1]}