author | Aurelien Campeas <aurelien.campeas@logilab.fr> |
Tue, 06 Apr 2010 18:36:09 +0200 | |
branch | stable |
changeset 5157 | 1202e6565aff |
parent 4441 | 550cf406dbc6 |
child 5189 | 84d4587a92bc |
permissions | -rw-r--r-- |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
1 |
|
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
2 |
|
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
3 |
API Python/RQL |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
4 |
~~~~~~~~~~~~~~ |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
5 |
|
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
6 |
The Python API developped to interface with RQL is inspired from the standard db-api, |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
7 |
with a Connection object having the methods cursor, rollback and commit essentially. |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
8 |
The most important method is the `execute` method of a cursor : |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
9 |
|
4441
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
10 |
`execute(rqlstring, args=None, cachekey=None, build_descr=True)` |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
11 |
|
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
12 |
:rqlstring: the RQL query to execute (unicode) |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
13 |
:args: if the query contains substitutions, a dictionary containing the values to use |
4441
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
14 |
:cachekey: |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
15 |
an implementation detail of the RQL cache implies that if a substitution |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
16 |
is used to introduce an eid *susceptible to raise the ambiguities in the query |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
17 |
type resolution*, then we have to specify the corresponding key in the dictionary |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
18 |
through this argument |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
19 |
|
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
20 |
|
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
21 |
The `Connection` object owns the methods `commit` and `rollback`. You *should |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
22 |
never need to use them* during the development of the web interface based on |
2175
16d3c37c5d28
[doc] improvements
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
1714
diff
changeset
|
23 |
the *CubicWeb* framework as it determines the end of the transaction depending |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
24 |
on the query execution success. |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
25 |
|
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
26 |
.. note:: |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
27 |
While executing update queries (SET, INSERT, DELETE), if a query generates |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
28 |
an error related to security, a rollback is automatically done on the current |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
29 |
transaction. |
4441
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
30 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
31 |
Executing RQL queries from a view or a hook |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
32 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
33 |
When you're within code of the web interface, the db-api like connexion is |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
34 |
handled by the request object. You should not have to access it directly, but |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
35 |
use the `execute` method directly available on the request, eg: |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
36 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
37 |
rset = self._cw.execute(rqlstring, kwargs) |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
38 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
39 |
Similarly, on the server side (eg in hooks), there is no db-api connexion (since |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
40 |
you're directly inside the data-server), so you'll have to use the execute method |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
41 |
of the session object. |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
42 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
43 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
44 |
Important note about proper usage of .execute |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
45 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
46 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
47 |
Let's say you want to get T which is in configuration C, this translates to: |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
48 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
49 |
.. sourcecode:: python |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
50 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
51 |
self._cw.execute('Any T WHERE T in_conf C, C eid %s' % entity.eid) |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
52 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
53 |
But it can also be written in a syntax that will benefit from the use |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
54 |
of a cache on the RQL server side: |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
55 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
56 |
.. sourcecode:: python |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
57 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
58 |
self._cw.execute('Any T WHERE T in_conf C, C eid %(x)s', {'x': entity.eid}, 'x') |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
59 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
60 |
Beside proper usage of the `args` argument, notice the latest argument: this is what's called |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
61 |
the cache key. The cache key should be either a string or a tuple containing the names of keys |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
62 |
in args which are referencing eids. *YOU MUST SET THIS PROPERLY* if you don't want weird result |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
63 |
on queries which have ambigous solutions deambiguified by specifing an eid. So the good habit is: |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
64 |
*always put in the cache key all eid keys*. |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
65 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
66 |
The syntax tree is build once for the "generic" RQL and can be re-used |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
67 |
with a number of different eid. |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
68 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
69 |
Alternativelly, some of the common data related to an entity can be obtained from |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
70 |
the top-level `entity.related()` method (which is used under the hood by the orm |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
71 |
when you use attribute access notation on an entity to get a relation. The above |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
72 |
would then be translated to: |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
73 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
74 |
.. sourcecode:: python |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
75 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
76 |
entity.related('in_conf', 'object') |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
77 |
|
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
78 |
The `related()` method, as more generally others orm methods, makes extensive use |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
79 |
of the cache mechanisms so you don't have to worry about them. Additionnaly this |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
80 |
use will get you commonly used attributes that you will be able to use in your |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
81 |
view generation without having to ask the data backend. |
550cf406dbc6
moved content to the dbapi section
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2175
diff
changeset
|
82 |