gavo.base.sqlsupport module¶
Basic support for communicating with the database server.
This is currently very postgres specific. If we really wanted to support some other database, this would need massive refactoring.
- class gavo.base.sqlsupport.AdhocQuerier(connectionManager=None)[source]¶
Bases:
QuerierMixin
A simple interface to querying the database through pooled connections.
These are constructed using the connection getters (getTableConn (default), getAdminConn) and then serve as context managers, handing back the connection as you exit the controlled block.
Since they operate through pooled connections, no transaction management takes place. These are typically for read-only things.
You can use the query method and everything that’s in the QuerierMixin.
- class gavo.base.sqlsupport.CustomConnectionPool(minconn, maxconn, profileName, autocommitted=True)[source]¶
Bases:
ThreadedConnectionPool
A threaded connection pool that returns connections made via profileName.
- knownPools = []¶
- class gavo.base.sqlsupport.DebugConnection[source]¶
Bases:
GAVOConnection
- cursor(*args, **kwargs)[source]¶
cursor(name=None, cursor_factory=extensions.cursor, withhold=False) – new cursor
Return a new cursor.
The
cursor_factory
argument can be used to create non-standard cursors by passing a class different from the default. Note that the new class should be a sub-class of extensions.cursor.- Return type:
extensions.cursor
- exception gavo.base.sqlsupport.Error(msg: str = '', hint: Optional[str] = None)[source]¶
Bases:
Error
- class gavo.base.sqlsupport.FloatableAdapter(val)[source]¶
Bases:
object
An adapter for things that do “float”, in particular numpy.float*
- class gavo.base.sqlsupport.GAVOConnection[source]¶
Bases:
connection
A psycopg2 connection with some additional methods.
This derivation is also done so we can attach the getDBConnection arguments to the connection; it is used when recovering from a database restart.
- configure(settings, cursor=None)[source]¶
sets a number of postgres connection parameters.
settings is a list of (parameter, value) pairs, where value must be a python value that psycopg2 understands and that works for the parameter in question.
This returns a settings-list that restores the previous values when passed to configure()
- execute(query, args={})[source]¶
executes query in a cursor.
This returns the rowcount of the cursor used.
- extensionFunctions = frozenset({'epoch_prop', 'healpix_nest', 'q3c_ang2ipix', 'smoc_union'})¶
- getParameter(key, cursor=None)[source]¶
returns the value of the postgres parameter key.
This returns unprocessed values, probably almost always as strings. Caveat emptor.
The main purpose of this function is to help the parameters connection manager, so users shouldn’t really mess with it.
- parameters(settings, cursor=None)[source]¶
executes a block with a certain set of parameters on a connection, resetting them to their original value again afterwards.
Of course, this only works as expected if you’re not sharing your connections to widely.
This rolls back the connection by itself on database errors; we couldn’t reset the parameters otherwise.
- query(query, args={}, timeout=None, yieldDicts=False, caseFixer=None)[source]¶
iterates over result tuples for query.
This is mainly for ad-hoc queries needing little metadata.
You can pass yieldDicts=True to get dictionaries instead of tuples. The dictionary keys are determined by what the database says the column titles are; thus, it’s usually lower-cased variants of what’s in the select-list. To fix this, you can pass in a caseFixer dict that gives a properly cased version of lowercase names.
Timeout is in seconds.
Warning: this is an iterator, so unless you iterate over the result, the query will not get executed. Hence, for non-select statements you will generally have to use conn.execute.
- queryToDicts(query, args={}, timeout=None, caseFixer=None)[source]¶
iterates over dictionary rows for query.
This is a thin wrapper around query(yieldDicts=True) provided for convenience and backwards compatibility.
- class gavo.base.sqlsupport.IntableAdapter(val)[source]¶
Bases:
object
An adapter for things that do “int”, in particular numpy.int*
- class gavo.base.sqlsupport.NULLAdapter(val)[source]¶
Bases:
object
An adapter for things that should end up as NULL in the DB.
- class gavo.base.sqlsupport.NonBlockingQuery(conn, query, args={})[source]¶
Bases:
object
a query run in a pseudo-nonblocking way.
While psycopg2 can do proper async, that doesn’t play well with about everything else DaCHS is doing so far. So, here’s a quick way to allow long-running queries that users can still interrupt. The ugly secret is that it’s based on threads.
This should not be used within the server. We might want to port the async taprunner (which runs outside of the server) to using this, though.
To use it, construct it with conn, query and perhaps args and use it as a context manager.
Wait for its result attribute to become non-None; this will then be either a list of result rows or an Exception (which will also be raised when exiting the context manager).
To abort a running query, call abort().
- class gavo.base.sqlsupport.PostgresQueryMixin[source]¶
Bases:
object
is a mixin containing various useful queries that are postgres specific.
This mixin expects a parent that mixes is QuerierMixin (that, for now, also mixes in PostgresQueryMixin, so you won’t need to mix this in).
- dropTable(tableName, cascade=False)[source]¶
drops a table or view named by tableName.
This does not raise an error if no such relation exists.
* postgres specific *
- getACLFromRes(thingWithPrivileges)[source]¶
returns a dict of (role, ACL) as it is defined in thingWithPrivileges.
thingWithPrivileges is something mixing in rscdef.common.PrivilegesMixin. (or has readProfiles and allProfiles attributes containing sequences of profile names).
- getColumnsFromDB(tableName)[source]¶
returns a sequence of (name, type) pairs of the columns this table has in the database.
If the table is not on disk, this will raise a NotFoundError.
* psycopg2 specific *
- getForeignKeyName(srcTableName, destTableName, srcColNames, destColNames, schema=None)[source]¶
returns True if there’s a foreign key constraint on srcTable’s srcColNames using destTableName’s destColNames.
Warning: names in XColNames that are not column names in the respective tables are ignored.
This raises a ValueError if the foreign keys do not exist.
- getOIDForTable(tableName, schema=None)[source]¶
returns the current oid of tableName.
tableName may be schema qualified. If it is not, public is assumed.
- getPrimaryIndexName(tableName)[source]¶
returns the name of the index corresponding to the primary key on (the unqualified) tableName.
- getRowEstimate(tableName)[source]¶
returns the size of the table in rows as estimated by the query planner.
This will raise a KeyError with tableName if the table isn’t known to postgres.
- getTablePrivileges(schema, tableName)[source]¶
returns (owner, readRoles, allRoles) for the relation tableName and the schema.
* postgres specific *
- getTableType(tableName, schema=None)[source]¶
returns the type of the relation relationName.
If relationName does not exist, None is returned. Otherwise, it’s what is in the information schema for the table, which for postgres currently is one of BASE TABLE, VIEW, FOREIGN TABLE, MATERIALIZED VIEW, or LOCAL TEMPORARY.
The DaCHS-idiomatic way to see if a relation exists is getTableType() is not None.
You can pass in schema-qualified relation names, or the relation name and the schema separately.
* postgres specific *
- class gavo.base.sqlsupport.QuerierMixin[source]¶
Bases:
PostgresQueryMixin
,StandardQueryMixin
is a mixin for “queriers”, i.e., objects that maintain a db connection.
The mixin assumes an attribute connection from the parent.
- defaultProfile = None¶
- query(query, data={}, timeout=None)[source]¶
wraps conn.query adding logic to re-establish lost connections.
Don’t use this method any more in new code. It contains wicked logic to tell DDL statements (that run without anyone pulling the results) from actual selects. That’s a bad API. Also note that the timeout is ignored for DDL statements.
We’ll drop this some time in 2023.
Use either connection.query or connection.execute in new code.
- class gavo.base.sqlsupport.SqlArrayAdapter(seq)[source]¶
Bases:
object
An adapter that formats python lists as SQL arrays
This makes, in the shameful tradition of VOTable, empty arrays equal to NULL.
- class gavo.base.sqlsupport.SqlSetAdapter(seq)[source]¶
Bases:
object
is an adapter that formats python sequences as SQL sets.
– as opposed to psycopg2’s apparent default of building arrays out of them.
- class gavo.base.sqlsupport.StandardQueryMixin[source]¶
Bases:
object
is a mixin containing various useful queries that should work against all SQL systems.
This mixin expects a parent that mixes is QuerierMixin (that, for now, also mixes in StandardQueryMixin, so you won’t need to mix this in).
The parent also needs to mix in something like PostgresQueryMixin (I might want to define an interface there once I’d like to support other databases).
- class gavo.base.sqlsupport.UnmanagedQuerier(connection)[source]¶
Bases:
QuerierMixin
A simple interface to querying the database through a connection managed by someone else.
This is typically used as in:
with base.getTableConn() as conn: q = UnmanagedQuerier(conn) ...
This contains numerous methods abstracting DB functionality a bit. Documented ones include:
schemaExists(schema)
getColumnsFromDB(tableName)
getTableType(tableName) – this will return None for non-existing tables, which is DaCHS’ official way to determine table existence.
- gavo.base.sqlsupport.adapter¶
alias of
IntableAdapter
- gavo.base.sqlsupport.getAdminConn()¶
- gavo.base.sqlsupport.getDBConnection(profile, debug=False, autocommitted=False)[source]¶
returns an enhanced database connection through profile.
You will typically rather use the context managers for the standard profiles (
getTableConnection
and friends). Use this function if you want to keep your connection out of connection pools or if you want to use non-standard profiles.profile will usually be a string naming a profile defined in
GAVO_ROOT/etc
.
- gavo.base.sqlsupport.getDBMeta(key)[source]¶
returns the value for key from within dc.metastore.
This always returns a unicode string. Type conversions are the client’s business.
If no value exists, this raises a KeyError.
- gavo.base.sqlsupport.getPgVersion(digits=2)[source]¶
returns the version number of the postgres server executing untrusted (ADQL) queries.
This is relatively expensive, as it will actually ask the server.
- gavo.base.sqlsupport.getTableConn()¶
- gavo.base.sqlsupport.getUntrustedConn()¶
- gavo.base.sqlsupport.getWritableAdminConn()¶
- gavo.base.sqlsupport.getWritableTableConn()¶
- gavo.base.sqlsupport.getWritableUntrustedConn()¶