gavo.rsc.dbtable module

Tables on disk

class gavo.rsc.dbtable.DBMethodsMixin[source]

Bases: QuerierMixin

is a mixin for on-disk tables.

The parent must have tableDef, tableName (from tabledef.getQName()), and connection attributes.

copyIn(inFile, binary=True)[source]
copyOut(outFile, binary=True)[source]
deleteMatching(matchCondition, pars={})[source]

deletes all rows matching matchCondition.

For now, matchCondition a boolean SQL expression. All rows matching it will be deleted.

dropIndices()[source]
ensureOnDiskMatches()[source]

raises a DataError if the on-disk structure of a table doesn’t match DaCHS’ idea of it.

If the table doesn’t exist on disk, this will raise a NotFoundError.

ensureSchema()[source]

creates self’s schema if necessary.

getDeleteQuery(matchCondition, pars={})[source]
makeIndices()[source]

creates all indices on the table, including any definition of a primary key.

scripts = None
class gavo.rsc.dbtable.DBTable(tableDef, **kwargs)[source]

Bases: DBMethodsMixin, BaseTable, MetaTableMixin

An interface to a table in the database.

These are usually created using api.TableForDef(tableDef) with a table definition obtained, e.g., from an RD, saying onDisk=True.

When constructing a DBTable, it will be created if necessary (unless create=False is passed), but indices or primary keys keys will only be created on a call to importFinished.

The constructor does not check if the schema of the table on disk matches the tableDef. If the two diverge, all kinds of failures are conceivable; use dachs val -c to make sure on-disk structure match the RDs.

You can pass a nometa boolean kw argument to suppress entering the table into the dc_tables table.

You can pass an exclusive boolean kw argument; if you do, the iterQuery (and possibly similar methods in the future) method will block concurrent writes to the selected rows (“FOR UPDATE”) as long as the transaction is active.

DbTables will run preCreation, preIndex, postCreation, and beforeDrop scripts, both from the table definition and the make they are being created from. No scripts except beforeDrop are run when an existing table is operated on from an updating dd.

The main attributes (with API guarantees) include:

  • tableDef – the defining tableDef

  • getFeeder() – returns a function you can call with rowdicts to insert them into the table.

  • importFinished(nImported) – must be called after you’ve fed all rows when importing data; pass the number of rows fed in.

  • drop() – drops the table in the database

  • recreate() – drops the table and generates a new empty one.

  • getTableForQuery(…) – returns a Table instance built from a query over this table (you probably to use conn.query* and td.getSimpleQuery instead).

addRow(row)[source]

adds a row to the table.

Use this only to add one or two rows, otherwise go for getFeeder.

create()[source]
createIfNecessary()[source]
createUniquenessRules()[source]
drop(seenIds=())[source]

drops the table.

This will recurse into dependent objects.

exists()[source]
feedRows(rows)[source]

Feeds a sequence of rows to the table.

The method returns the number of rows affected. Exceptions are handed through upstream, but the connection is rolled back.

getFeeder(**kwargs)[source]
getQuery(resultTableDef, fragment, pars=None, distinct=False, limits=None, groupBy=None, samplePercent=None)[source]

returns a result table definition, query string and a parameters dictionary for a query against this table.

See getTableForQuery for the meaning of the arguments.

getRow(*key)[source]

returns the row with the primary key key from the table.

This will raise a DataError on tables without primaries.

getSelectClause(resultTableDef)[source]

returns the select clause to come up with resultTableDef.

getTableForQuery(resultTableDef=None, fragment='', pars=None, distinct=False, limits=None, groupBy=None, samplePercent=None)[source]

returns a Table instance for a query on this table.

resultTableDef is a TableDef with svc.OutputField columns (rscdef.Column instances will do), or possibly just a list of Columns. Fragment is empty or an SQL where-clause with dictionary placeholders, pars is the dictionary filling fragment, distinct, if True, adds a distinct clause, and limits, if given, is a pair of an SQL string to be appended to the SELECT clause and parameters filling it. queryMeta.asSQL returns what you need here.

pars may be mutated in the process.

importFailed(*excInfo)[source]
importFinished(nAffected)[source]
iterQuery(resultTableDef=None, fragment='', pars=None, distinct=False, limits=None, groupBy=None)[source]

like getTableForQuery, except that an iterator over the result rows is returned.

(there is no advantage in using this as we will pull the entire thing in memory anyway; use qtables if you need streaming).

query(query, data={})[source]

runs query within this table’s connection.

query is macro-expanded within the table definition (i.e., you can, e.g., write qName to obtain the table’s qualified name).

Don’t use this in new code; use t.connection.query or execute as required.

recreate()[source]
runScripts(phase, **kwargs)[source]

runs scripts from both the tableDef and the make.

The reason there’s not a single place is mainly historical; on the other hand, one day postCreation scripts only run when a table is created in a special way might come in handy, so I’ll not take away table scripts from makes.

setStatisticsTargets()[source]
updateMeta()[source]
class gavo.rsc.dbtable.MetaTableMixin[source]

Bases: object

is a mixin providing methods updating the dc_tables.

It requires a tableDef attribute on the parent, and the parent must mix in QuerierMixin.

addToMeta()[source]
cleanFromMeta()[source]
class gavo.rsc.dbtable.View(*args, **kwargs)[source]

Bases: DBTable

is a view, i.e., a table in the database you can’t add to.

Strictly, I should derive both View and DBTable from a common base, but that’s currently not worth the effort.

Technically, Views are DBTables with a non-None viewStatement (this is what TableForDef checks for when deciding whether to construct a DBTable or a View). You can get a feeder for them, but trying to actually feed anything will raise a DataError.

On import, views only run postCreation scripts; we assume everything else (preIndex, postIndex, preImport, newSource, etc) has run in the contributing tables. Materialised views will create indices, however.

addRow(row)[source]

adds a row to the table.

Use this only to add one or two rows, otherwise go for getFeeder.

create()[source]
feedRows(row)

Feeds a sequence of rows to the table.

The method returns the number of rows affected. Exceptions are handed through upstream, but the connection is rolled back.

getFeeder(**kwargs)[source]
importFinished(nImported)[source]
makeIndices()[source]

creates all indices on the table, including any definition of a primary key.

setStatisticsTargets()[source]