Coverage.py database schema¶
New in version 5.0.
Coverage.py stores data in a SQLite database, by default called
For most needs, the
CoverageData API will be sufficient, and should
be preferred to accessing the database directly. Only advanced uses will need
to use the database.
The schema can change without changing the major version of coverage.py, so be careful when accessing the database directly. The coverage_schema table has the schema number of the database. The schema described here corresponds to:
SCHEMA_VERSION = 7
You can use SQLite tools such as the
sqlite3 module in
the Python standard library to access the data. Some data is stored in a
packed format that will need custom functions to access. See
This is the database schema.
TODO: explain more. Readers: what needs explaining?
CREATE TABLE coverage_schema ( -- One row, to record the version of the schema in this db. version integer ); CREATE TABLE meta ( -- Key-value pairs, to record metadata about the data key text, value text, unique (key) -- Keys: -- 'has_arcs' boolean -- Is this data recording branches? -- 'sys_argv' text -- The coverage command line that recorded the data. -- 'version' text -- The version of coverage.py that made the file. -- 'when' text -- Datetime when the file was created. ); CREATE TABLE file ( -- A row per file measured. id integer primary key, path text, unique (path) ); CREATE TABLE context ( -- A row per context measured. id integer primary key, context text, unique (context) ); CREATE TABLE line_bits ( -- If recording lines, a row per context per file executed. -- All of the line numbers for that file/context are in one numbits. file_id integer, -- foreign key to `file`. context_id integer, -- foreign key to `context`. numbits blob, -- see the numbits functions in coverage.numbits foreign key (file_id) references file (id), foreign key (context_id) references context (id), unique (file_id, context_id) ); CREATE TABLE arc ( -- If recording branches, a row per context per from/to line transition executed. file_id integer, -- foreign key to `file`. context_id integer, -- foreign key to `context`. fromno integer, -- line number jumped from. tono integer, -- line number jumped to. foreign key (file_id) references file (id), foreign key (context_id) references context (id), unique (file_id, context_id, fromno, tono) ); CREATE TABLE tracer ( -- A row per file indicating the tracer used for that file. file_id integer primary key, tracer text, foreign key (file_id) references file (id) );
Functions to manipulate packed binary representations of number sets.
To save space, coverage stores sets of line numbers in SQLite using a packed binary representation called a numbits. A numbits is a set of positive integers.
A numbits is stored as a blob in the database. The exact meaning of the bytes in the blobs should be considered an implementation detail that might change in the future. Use these functions to work with those binary blobs of data.
- coverage.numbits.num_in_numbits(num, numbits)¶
Does the integer num appear in numbits?
A bool, True if num is a member of numbits.
- coverage.numbits.numbits_any_intersection(numbits1, numbits2)¶
Is there any number that appears in both numbits?
Determine whether two number sets have a non-empty intersection. This is faster than computing the intersection.
A bool, True if there is any number in both numbits1 and numbits2.
- coverage.numbits.numbits_intersection(numbits1, numbits2)¶
Compute the intersection of two numbits.
A new numbits, the intersection numbits1 and numbits2.
Convert a numbits into a list of numbers.
numbits – a binary blob, the packed number set.
A list of ints.
When registered as a SQLite function by
register_sqlite_functions(), this returns a string, a JSON-encoded list of ints.
- coverage.numbits.numbits_union(numbits1, numbits2)¶
Compute the union of two numbits.
A new numbits, the union of numbits1 and numbits2.
Convert nums into a numbits.
nums – a reusable iterable of integers, the line numbers to store.
A binary blob.
Define numbits functions in a SQLite connection.
This defines these functions for use in SQLite statements:
connection is a
sqlite3.Connectionobject. After creating the connection, pass it to this function to register the numbits functions. Then you can use numbits functions in your queries:
import sqlite3 from coverage.numbits import register_sqlite_functions conn = sqlite3.connect('example.db') register_sqlite_functions(conn) c = conn.cursor() # Kind of a nonsense query: find all the files and contexts that # executed line 47 in any file: c.execute( "select file_id, context_id from line_bits where num_in_numbits(?, numbits)", (47,) )