35 with self.repo.internal_cnx() as cnx: |
36 with self.repo.internal_cnx() as cnx: |
36 do_stuff_with(cnx) |
37 do_stuff_with(cnx) |
37 cnx.commit() |
38 cnx.commit() |
38 |
39 |
39 Connections should always be used as context managers, to avoid leaks. |
40 Connections should always be used as context managers, to avoid leaks. |
|
41 |
|
42 |
|
43 Python/RQL API |
|
44 ~~~~~~~~~~~~~~ |
|
45 |
|
46 The Python API developped to interface with RQL is inspired from the standard db-api, |
|
47 but since `execute` returns its results directly, there is no `cursor` concept. |
|
48 |
|
49 .. sourcecode:: python |
|
50 |
|
51 execute(rqlstring, args=None, build_descr=True) |
|
52 |
|
53 :rqlstring: the RQL query to execute (unicode) |
|
54 :args: if the query contains substitutions, a dictionary containing the values to use |
|
55 |
|
56 The `Connection` object owns the methods `commit` and `rollback`. You |
|
57 *should never need to use them* during the development of the web |
|
58 interface based on the *CubicWeb* framework as it determines the end |
|
59 of the transaction depending on the query execution success. They are |
|
60 however useful in other contexts such as tests or custom controllers. |
|
61 |
|
62 .. note:: |
|
63 |
|
64 If a query generates an error related to security (:exc:`Unauthorized`) or to |
|
65 integrity (:exc:`ValidationError`), the transaction can still continue but you |
|
66 won't be able to commit it, a rollback will be necessary to start a new |
|
67 transaction. |
|
68 |
|
69 Also, a rollback is automatically done if an error occurs during commit. |
|
70 |
|
71 .. note:: |
|
72 |
|
73 A :exc:`ValidationError` has a `entity` attribute. In CubicWeb, |
|
74 this atttribute is set to the entity's eid (not a reference to the |
|
75 entity itself). |
|
76 |
|
77 Executing RQL queries from a view or a hook |
|
78 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
79 |
|
80 When you're within code of the web interface, the Connection is handled by the |
|
81 request object. You should not have to access it directly, but use the |
|
82 `execute` method directly available on the request, eg: |
|
83 |
|
84 .. sourcecode:: python |
|
85 |
|
86 rset = self._cw.execute(rqlstring, kwargs) |
|
87 |
|
88 Similarly, on the server side (eg in hooks), there is no request object (since |
|
89 you're directly inside the data-server), so you'll have to use the execute method |
|
90 of the Connection object. |
|
91 |
|
92 Proper usage of `.execute` |
|
93 ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
94 |
|
95 Let's say you want to get T which is in configuration C, this translates to: |
|
96 |
|
97 .. sourcecode:: python |
|
98 |
|
99 self._cw.execute('Any T WHERE T in_conf C, C eid %s' % entity.eid) |
|
100 |
|
101 But it must be written in a syntax that will benefit from the use |
|
102 of a cache on the RQL server side: |
|
103 |
|
104 .. sourcecode:: python |
|
105 |
|
106 self._cw.execute('Any T WHERE T in_conf C, C eid %(x)s', {'x': entity.eid}) |
|
107 |
|
108 The syntax tree is built once for the "generic" RQL and can be re-used |
|
109 with a number of different eids. The rql IN operator is an exception |
|
110 to this rule. |
|
111 |
|
112 .. sourcecode:: python |
|
113 |
|
114 self._cw.execute('Any T WHERE T in_conf C, C name IN (%s)' |
|
115 % ','.join(['foo', 'bar'])) |
|
116 |
|
117 Alternatively, some of the common data related to an entity can be |
|
118 obtained from the `entity.related()` method (which is used under the |
|
119 hood by the ORM when you use attribute access notation on an entity to |
|
120 get a relation. The initial request would then be translated to: |
|
121 |
|
122 .. sourcecode:: python |
|
123 |
|
124 entity.related('in_conf', 'object') |
|
125 |
|
126 Additionally this benefits from the fetch_attrs policy (see :ref:`FetchAttrs`) |
|
127 optionally defined on the class element, which says which attributes must be |
|
128 also loaded when the entity is loaded through the ORM. |
|
129 |
|
130 .. _resultset: |
|
131 |
|
132 The `ResultSet` API |
|
133 ~~~~~~~~~~~~~~~~~~~ |
|
134 |
|
135 ResultSet instances are a very commonly manipulated object. They have |
|
136 a rich API as seen below, but we would like to highlight a bunch of |
|
137 methods that are quite useful in day-to-day practice: |
|
138 |
|
139 * `__str__()` (applied by `print`) gives a very useful overview of both |
|
140 the underlying RQL expression and the data inside; unavoidable for |
|
141 debugging purposes |
|
142 |
|
143 * `printable_rql()` returns a well formed RQL expression as a |
|
144 string; it is very useful to build views |
|
145 |
|
146 * `entities()` returns a generator on all entities of the result set |
|
147 |
|
148 * `get_entity(row, col)` gets the entity at row, col coordinates; one |
|
149 of the most used result set methods |
|
150 |
|
151 .. autoclass:: cubicweb.rset.ResultSet |
|
152 :members: |
|
153 |
40 |
154 |
41 Authentication and management of sessions |
155 Authentication and management of sessions |
42 ----------------------------------------- |
156 ----------------------------------------- |
43 |
157 |
44 The authentication process is a ballet involving a few dancers: |
158 The authentication process is a ballet involving a few dancers: |