The Python API developped to interface with RQL is inspired from the standard db-api, with a Connection object having the methods cursor, rollback and commit essentially. The most important method is the execute method of a cursor.
execute(rqlstring, args=None, build_descr=True)
rqlstring: | the RQL query to execute (unicode) |
---|---|
args: | if the query contains substitutions, a dictionary containing the values to use |
The Connection object owns the methods commit and rollback. You should never need to use them during the development of the web interface based on the CubicWeb framework as it determines the end of the transaction depending on the query execution success. They are however useful in other contexts such as tests or custom controllers.
Note
If a query generates an error related to security (Unauthorized) or to integrity (ValidationError), the transaction can still continue but you won’t be able to commit it, a rollback will be necessary to start a new transaction.
Also, a rollback is automatically done if an error occurs during commit.
Note
A ValidationError has a entity attribute. In CubicWeb, this atttribute is set to the entity’s eid (not a reference to the entity itself).
When you’re within code of the web interface, the db-api like connexion is handled by the request object. You should not have to access it directly, but use the execute method directly available on the request, eg:
rset = self._cw.execute(rqlstring, kwargs)
Similarly, on the server side (eg in hooks), there is no db-api connexion (since you’re directly inside the data-server), so you’ll have to use the execute method of the session object.
Let’s say you want to get T which is in configuration C, this translates to:
self._cw.execute('Any T WHERE T in_conf C, C eid %s' % entity.eid)
But it must be written in a syntax that will benefit from the use of a cache on the RQL server side:
self._cw.execute('Any T WHERE T in_conf C, C eid %(x)s', {'x': entity.eid})
The syntax tree is built once for the “generic” RQL and can be re-used with a number of different eids. There rql IN operator is an exception to this rule.
self._cw.execute('Any T WHERE T in_conf C, C name IN (%s)'
% ','.join(['foo', 'bar']))
Alternativelly, some of the common data related to an entity can be obtained from the entity.related() method (which is used under the hood by the orm when you use attribute access notation on an entity to get a relation. The initial request would then be translated to:
entity.related('in_conf', 'object')
Additionnaly this benefits from the fetch_attrs policy (see Loaded attributes and default sorting management) eventually defined on the class element, which says which attributes must be also loaded when the entity is loaded through the orm.
ResultSet instances are a very commonly manipulated object. They have a rich API as seen below, but we would like to highlight a bunch of methods that are quite useful in day-to-day practice:
A result set wraps a RQL query result. This object implements partially the list protocol to allow direct use as a list of result rows.
Parameters: |
|
---|
return the list of different types in the column with the given col
Parameters: | col (int) – the index of the desired column |
---|---|
Return type: | list |
Returns: | the different entities type found in the column |
short cut to get an completed entity instance for a particular row (all instance’s attributes have been fetched)
return a list describing sequence of results with the same description, e.g. : [[0, 4, (‘Bug’,)] [[0, 4, (‘Bug’,), [5, 8, (‘Story’,)] [[0, 3, (‘Project’, ‘Version’,)]]
iter on entities with eid in the col column of the result set
filter the result set according to a given filtercb
Parameters: |
|
---|---|
Return type: | ResultSet |
convenience method for query retrieving a single entity, returns a partially initialized Entity instance.
Warning
Due to the cache wrapping this function, you should NEVER give row as a named parameter (i.e. rset.get_entity(0, 1) is OK but rset.get_entity(row=0, col=1) isn’t)
Parameters: | row,col (int, int) – row and col numbers localizing the entity among the result’s table |
---|---|
Returns: | the partially initialized Entity instance |
iterates over rows, and for each row eids are converted to plain entities
limit the result set to the given number of rows optionaly starting from an index different than 0
Parameters: |
|
---|---|
Return type: | ResultSet |
returns a printable rql for the result set associated to the object, with limit/offset correctly set according to maximum page size and currently displayed page when necessary
Retrieve exactly one entity from the query.
If the result set is empty, raises NoResultError. If the result set has more than one row, raises MultipleResultsError.
Parameters: | col (int) – The column localising the entity in the unique row |
---|---|
Returns: | the partially initialized Entity instance |
return the result set’s origin rql as a string, with arguments substitued
given an cell of the result set, try to return a (entity, relation name) tuple to which this cell is linked.
This is especially useful when the cell is an attribute of an entity, to get the entity to which this attribute belongs to.
returns the searched text in case of full-text search
Returns: | searched text or None if the query is not a full-text query |
---|
sorts the result set according to a given keyfunc
Parameters: |
|
---|---|
Return type: | ResultSet |
splits the result set in multiple result sets according to a given key
Parameters: |
|
---|---|
Return type: | List of ResultSet or mapping of ResultSet |
return the syntax tree (rql.stmts.Union) for the originating query. You can expect it to have solutions computed but it won’t be annotated (you usually don’t need that for simple introspection).
the result set according to a given column types
Parameters: |
|
---|---|
Return type: | ResultSet |
The whole cursor API is developped below.
Note
In practice you’ll usually use the .execute method on the _cw object of appobjects. Usage of other methods is quite rare.
These objects represent a database cursor, which is used to manage the context of a fetch operation. Cursors created from the same connection are not isolated, i.e., any changes done to the database by a cursor are immediately visible by the other cursors. Cursors created from different connections are isolated.
This read-only attribute return a reference to the Connection object on which the cursor was created.
no effect
optionnal issuing request instance
execute a rql query, return resulting rows and their description in a ResultSet object
on INSERT queries, there will be one row for each inserted entity, containing its eid
on SET queries, XXX describe
DELETE queries returns no result.
Note
to maximize the rql parsing/analyzing cache performance, you should always use substitute arguments in queries, i.e. avoid query such as:
execute('Any X WHERE X eid 123')
use:
execute('Any X WHERE X eid %(x)s', {'x': 123})
DB-API 2.0 compatible Connection object for CubicWeb
Exception raised for errors that are related to the database’s operation and not necessarily under the control of the programmer, e.g. an unexpected disconnect occurs, the data source name is not found, a transaction could not be processed, a memory allocation error occurred during processing, etc.
alias of Cursor
return True if this is a local, aka in-memory, connection to the repository
monkey patch DBAPIRequest to fake a cw.web.request, so you should able to call html views using rset from a simple dbapi connection.
You should call load_appobjects at some point to register those views.