3 API Python/RQL |
3 API Python/RQL |
4 ~~~~~~~~~~~~~~ |
4 ~~~~~~~~~~~~~~ |
5 |
5 |
6 The Python API developped to interface with RQL is inspired from the standard db-api, |
6 The Python API developped to interface with RQL is inspired from the standard db-api, |
7 with a Connection object having the methods cursor, rollback and commit essentially. |
7 with a Connection object having the methods cursor, rollback and commit essentially. |
8 The most important method is the `execute` method of a cursor : |
8 The most important method is the `execute` method of a cursor. |
9 |
9 |
10 `execute(rqlstring, args=None, cachekey=None, build_descr=True)` |
10 .. sourcecode:: python |
|
11 execute(rqlstring, args=None, cachekey=None, build_descr=True) |
11 |
12 |
12 :rqlstring: the RQL query to execute (unicode) |
13 :rqlstring: the RQL query to execute (unicode) |
13 :args: if the query contains substitutions, a dictionary containing the values to use |
14 :args: if the query contains substitutions, a dictionary containing the values to use |
14 :cachekey: |
15 :cachekey: |
15 an implementation detail of the RQL cache implies that if a substitution |
16 an implementation detail of the RQL cache implies that if a substitution |
16 is used to introduce an eid *susceptible to raise the ambiguities in the query |
17 is used to introduce an eid *susceptible to raise the ambiguities in the query |
17 type resolution*, then we have to specify the corresponding key in the dictionary |
18 type resolution*, then we have to specify the corresponding key in the dictionary |
18 through this argument |
19 through this argument |
19 |
20 |
20 |
21 |
21 The `Connection` object owns the methods `commit` and `rollback`. You *should |
22 The `Connection` object owns the methods `commit` and `rollback`. You |
22 never need to use them* during the development of the web interface based on |
23 *should never need to use them* during the development of the web |
23 the *CubicWeb* framework as it determines the end of the transaction depending |
24 interface based on the *CubicWeb* framework as it determines the end |
24 on the query execution success. |
25 of the transaction depending on the query execution success. They are |
|
26 however useful in other contexts such as tests. |
25 |
27 |
26 .. note:: |
28 .. note:: |
27 While executing update queries (SET, INSERT, DELETE), if a query generates |
29 While executing update queries (SET, INSERT, DELETE), if a query generates |
28 an error related to security, a rollback is automatically done on the current |
30 an error related to security, a rollback is automatically done on the current |
29 transaction. |
31 transaction. |
30 |
32 |
31 Executing RQL queries from a view or a hook |
33 Executing RQL queries from a view or a hook |
32 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
34 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
35 |
33 When you're within code of the web interface, the db-api like connexion is |
36 When you're within code of the web interface, the db-api like connexion is |
34 handled by the request object. You should not have to access it directly, but |
37 handled by the request object. You should not have to access it directly, but |
35 use the `execute` method directly available on the request, eg: |
38 use the `execute` method directly available on the request, eg: |
36 |
39 |
37 rset = self._cw.execute(rqlstring, kwargs) |
40 rset = self._cw.execute(rqlstring, kwargs) |
48 |
51 |
49 .. sourcecode:: python |
52 .. sourcecode:: python |
50 |
53 |
51 self._cw.execute('Any T WHERE T in_conf C, C eid %s' % entity.eid) |
54 self._cw.execute('Any T WHERE T in_conf C, C eid %s' % entity.eid) |
52 |
55 |
53 But it can also be written in a syntax that will benefit from the use |
56 But it must be written in a syntax that will benefit from the use |
54 of a cache on the RQL server side: |
57 of a cache on the RQL server side: |
55 |
58 |
56 .. sourcecode:: python |
59 .. sourcecode:: python |
57 |
60 |
58 self._cw.execute('Any T WHERE T in_conf C, C eid %(x)s', {'x': entity.eid}, 'x') |
61 self._cw.execute('Any T WHERE T in_conf C, C eid %(x)s', {'x': entity.eid}) |
59 |
62 |
60 Beside proper usage of the `args` argument, notice the latest argument: this is what's called |
63 The syntax tree is built once for the "generic" RQL and can be re-used |
61 the cache key. The cache key should be either a string or a tuple containing the names of keys |
64 with a number of different eids. |
62 in args which are referencing eids. *YOU MUST SET THIS PROPERLY* if you don't want weird result |
|
63 on queries which have ambigous solutions deambiguified by specifing an eid. So the good habit is: |
|
64 *always put in the cache key all eid keys*. |
|
65 |
|
66 The syntax tree is build once for the "generic" RQL and can be re-used |
|
67 with a number of different eid. |
|
68 |
65 |
69 Alternativelly, some of the common data related to an entity can be obtained from |
66 Alternativelly, some of the common data related to an entity can be obtained from |
70 the top-level `entity.related()` method (which is used under the hood by the orm |
67 the top-level `entity.related()` method (which is used under the hood by the orm |
71 when you use attribute access notation on an entity to get a relation. The above |
68 when you use attribute access notation on an entity to get a relation. The above |
72 would then be translated to: |
69 would then be translated to: |