Direct Database Access

Some methods, properties are not fully exposed via the APIs, or are extremely slow or difficult to retrieve. Direct database access can be used with an abundance of caution and the caveat that it’s not guaranteed to work in future releases without modification.

Credentials and Connecting

Credential Configuration

class hammers.mycnf.MyCnf(paths=None)[source]

MySQL configuration fetcher. Attempts to emulate the behavior of the MySQL client to the best of its ability, falling through multiple locations where configuration could exist to determine its value.

class hammers.mysqlargs.MySqlArgs(defaults, mycnfpaths=None)[source]

Argument manager that combines command-line arguments with configuration files to determine MySQL connection info including the username, password, hostname, and port.

The defaults provided take the lowest priority. If any value is found among the configuration files with a higher priority, it overrides it. The key names used are user, password, host, and port.


Uses the prepared connection arguments and creates a hammers.mysqlshim.MySqlShim object that connects to the database.


Parses the arguments in the namespace returned by argparse.ArgumentParser.parse_args() to generate the final set of connection arguments.


Adds arguments to a argparse.ArgumentParser.

  • -u/--db-user
  • -p/--password
  • -H/--host
  • -P/--port
  • --service-conf: A configuration file like /etc/ironic/ironic.conf that contains a database connection string.


class hammers.mysqlshim.MySqlShim(**connect_args)[source]

Connection manager and query executor. connect_args is passed directly to MySQLdb.connect()

This class provides some quality-of-life stuff like providing column names and emitting dictionaries for rows.


Returns column names from the most recent query.

query(*cargs, **ckwargs)[source]

Parameters not listed are passed into the MySQLdb.cursors.Cursor’s execute function. One that is common would be args for parameterized queries.

  • no_rows (bool) – Executes the query and returns the number of rows updated. Very likely what you want for anything that modifies the database or else you may not complete the transaction.
  • immediate (bool) – If true, immediately runs the query and puts it into a list. Otherwise, an iterator is returned.



Decorator to include all the queries into a dictionary


The name of the column changed somewhere between L and O.

Should be pretty basic to avoid any SQL injection.


Returns rows enumerating all projects that are currently idle (number of running instances = 0). Also provides since when the project has been idle (when the latest running instance was deleted)

There may be NULLs emitted for “latest_deletion” if a project hasn’t ever had an instance (like an admin project…).

hammers.query.latest_instance_interaction(db, kvm, nova_db_name='nova')[source]

Get the latest interaction date with instances on the target database name. Combine as you so desire.

hammers.query.owned_ips(db, project_ids)[source]

Return all IPs associated with project_ids

Maria 5.5 in production doesn’t seem to like this, but works fine with a local MySQL 5.7. Is it Maria? 5.5? Too many? See owned_ip_single for one that works, but need to call multiple times.


Get project IDs with lease end dates in the future that haven’t been deleted. This will also grab active leases, but that’s erring on the safe side.

hammers.query.clear_ironic_port_internalinfo(db, port_id)[source]

Remove internal_info data from ports. When the data wasn’t cleaned up, it appeared to block other instances from spawning on the node. Now it may not be required? More research needed.

hammers.query.remove_extra_capability(db, host_id, capability_name)[source]

Remove an extra capability by name from host_id. (HTTP API doesn’t support this as of Feb 2018)


Run queries!