doc/book/en/development/devcore/dbapi.rst
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 03 Feb 2010 19:26:35 +0100
changeset 4441 550cf406dbc6
parent 2175 16d3c37c5d28
child 5189 84d4587a92bc
permissions -rw-r--r--
moved content to the dbapi section
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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