doc/book/en/development/devcore/dbapi.rst
branchstable
changeset 5189 84d4587a92bc
parent 4441 550cf406dbc6
child 5190 73bdc50d6af1
equal deleted inserted replaced
5188:99cdb9608cc1 5189:84d4587a92bc
     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: