Changes between Version 27 and Version 28 of TracDev/DatabaseApi
- Timestamp:
- Sep 8, 2012, 2:32:11 PM (12 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
TracDev/DatabaseApi
v27 v28 1 1 = Trac SQL Database API = 2 2 3 Trac uses a very thin layer on top of the standard [http://www.python.org/peps/pep-0249.html Python Database API 2.0] for interfacing with supported relational database systems such as [http://sqlite.org/ SQLite] or [http://www.postgresql.org/ PostgreSQL]. 4 5 ''Note that Trac prior to version 0.9 used the PySQLite APIs directly, and has no support for other database systems. This document describes the thin DB API abstraction layer introduced in version 0.9.'' 3 Trac uses a very thin layer on top of the standard [http://www.python.org/peps/pep-0249.html Python Database API 2.0] for interfacing with supported relational database systems such as [http://sqlite.org/ SQLite], [http://www.postgresql.org/ PostgreSQL] or the MySqlDb systems. 6 4 7 5 You can find the specifics of the database API in the [source:/trunk/trac/db/ trac.db] package. This package provides: … … 10 8 * Selection of DB modules based of connection URIs. 11 9 10 12 11 == Accessing the Database == 13 12 14 13 The DB API has evolved quite a lot in the recent versions of Trac, and the usage is substantially different whether you're working with Trac 0.11, 0.12 or 1.0 and up. 15 14 15 If you don't need to be encumbered with the legacy styles, skip directly to the [#Trac1.0API] style described below. 16 16 17 17 === API before Trac 0.12 18 18 19 //This is how things used to be for Trac 0.5 - 0.11, and is still supported in Trac 0.12, but in new code this style should be definitely **not**used, as it introduces all the problems that the new styles are solving (see next sections for details). //19 //This is how things used to be for Trac 0.5 - 0.11, and is still supported in Trac 0.12, but in new code this style should definitely **not** be used, as it introduces all the problems that the new styles are solving (see next sections for details). // 20 20 21 21 Code accessing the database in Trac go through this layer simply by using the {{{Environment}}} method {{{get_db_cnx()}}} in order to get a pooled database connection. A database cursor can be obtained from the pooled database connection, and the code uses the cursor in conjunction with SQL statements to implement the behavior. … … 91 91 This means that either the ''whole'' (outer) transaction is committed or aborted. So even if the nested transaction succeeded but the outer transaction fails (an exception is raised at the line with the "commit or rollback" comment), the ''whole'' transaction will be rolled back (i.e. including the changes made by the nested transaction). 92 92 93 ''Note:'' Using `env.get_read_db()` within a transaction reuses the same connection as used for the connection. So uncommitted changes made by the transaction will already be visible to the caller of `get_read_db()` (but not outside of the transaction - that is in another thread). 94 95 ''Note:'' Uncommited changes of a transaction are only visible to nested transactions in the same thread. Different threads use different database connections and therefore different transactions. 96 97 === Trac 1.0 API #Trac0.13API 98 93 ''Notes:'' 94 - While still possible in the API (for backward compatibility reasons), you should **not** call `commit()` yourself in transaction; not only does this happen automatically at the proper time (as explained above), if you'd call it yourself you will risk to commit from within a nested transaction, possibly leading to inconsistent state of the DB 95 - Using `env.get_read_db()` within a transaction reuses the same connection as used for the connection. So uncommitted changes made by the transaction will already be visible to the caller of `get_read_db()` (but not outside of the transaction - that is in another thread). 96 - Uncommited changes of a transaction are only visible to nested transactions in the same thread. Different threads use different database connections and therefore different transactions (well, to be more precise, the exact detail of what is visible to other threads is backend specific and depends to the //isolation level// used) 97 98 === Trac 1.0 API 99 [=#Trac0.13API] 99 100 // This style is supported for version 1.0.x, 1.1.x and will be supported beyond as well. // 100 101 … … 111 112 }}} 112 113 113 It does essentially the same thing as the 0.12 version above in a terser way. 114 It does essentially the same thing as the 0.12 version above in a terser way. Nested transactions work the way you'd expect (only the outermost one will actually do the `commit()`, upon normal exit) so, again, don't call `commit()` by yourself. 114 115 115 116 **The use of `env.get_db_cnx()` is now strongly discouraged.** … … 166 167 167 168 === Configuration 168 The {{{get_db_cnx}}} methodlooks at the value of the {{{database}}} configuration option in [wiki:TracIni trac.ini], which should contain a database connection URI. The default value for this option tells Trac to use an SQLite database inside the environment directory:169 For determining which database has to be used, Trac looks at the value of the {{{database}}} configuration option in [wiki:TracIni trac.ini], which should contain a database connection URI. The default value for this option tells Trac to use an SQLite database inside the environment directory: 169 170 170 171 {{{ … … 177 178 === Pooled Connections === 178 179 179 Trac used to operate the following way:180 Prior to version 1.0, Trac used to operate the following way: 180 181 The {{{Environment}}} method {{{get_db_cnx()}}} returns a connection from the pool of connections. This connection needs to be returned, and Trac is written so that the return will happen automatically by the garbage collector if the code is written to follow a simple rule. When the garbage collector determines the pooled database connection is no longer being used, its `__del__` method will return the pooled connection to the pool for reuse. If you have set a lexical variable in the function's body to the pooled connection, this typically occurs when the function is returning. In the example above of {{{myFunc}}} it occurs at the return statement since {{{db}}} is a variable local to {{{myFunc}}} 181 182 182 With the context managers introduced in Trac 0.13, we're able to return this Connection to the pool in a much more robust and direct way:183 With the context managers introduced in Trac 1.0, we're able to return this Connection to the pool in a much more robust and direct way: 183 184 When the control flow exits a context manager (either `Environment.db_query` or `Environment.db_transaction`), and if that context manager is the "outermost" one in case multiple contexts where nested, then the `Connection` is immediately returned to the pool, regardless of the behavior of the garbage collector. 184 185