Changes between Version 15 and Version 16 of TracDev/DatabaseApi
- Timestamp:
- Sep 25, 2010, 2:30:37 PM (14 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
TracDev/DatabaseApi
v15 v16 84 84 """, (param1, param2)) 85 85 # Execute some SQL "SELECT" statements 86 # (continue) 86 87 }}} 87 88 88 This one enforces the notion of read-access, because the `db` connection bound to the context doesn't support the `commit()` or `rollback()` methods. As there's no t `commit()` upon exit, one could question the usefulness of this syntactic construct. The main interest is in better locality of the connection: in order to improve concurrency, the lifetime of a connection wrapper has to be as short as possible (see #3446).89 This one enforces the notion of read-access, because the `db` connection bound to the context doesn't support the `commit()` or `rollback()` methods. As there's no `commit()` upon exit, one could question the usefulness of this syntactic construct. The main interest is in better locality of the connection: in order to improve concurrency, the lifetime of a connection wrapper has to be as short as possible (see #3446). Therefore, we close the connection on exit, making it available to other threads. So even if Python gives you access to the `db` variable after the `with` block (at the //`# (continue)`// line in the above example), you should not (and can't) use it at that point. 89 90 90 However, there's maybe an even better/shorter way to achieve this, with an execute helper function: 91 Actually, if you don't need to do anything fancy with the cursor like calling `db.get_last_id(cursor, ...)`, then you can use a shorter form: 92 {{{ 93 #!python 94 from trac.env import Environment 95 def myFunc(): 96 env = Environment('/path/to/projenv') 97 with env.db_query as db: 98 for a, b, c in db(""" 99 SELECT a, b, c 100 FROM ... 101 """, (param1, param2)): 102 # do something with a, b, c 103 }}} 104 105 All the results are returned at once in a list, by calling `fetchall()` on the underlying cursor. This is fine most of the time, if you need to limit the number of returned results, you can still use "LIMIT" or "OFFSET" in the SQL query. 106 107 In the same spirit, if you don't even need to use `db` itself for things like `db.cast()` or `db.like()`, you can simply do: 91 108 92 109 {{{ … … 95 112 def myFunc(): 96 113 env = Environment('/path/to/projenv') 97 with env.db_query as db:98 for a, b, c in db.execute("""99 SELECT a, b, cFROM ...114 for a, b, c in env.db_query(""" 115 SELECT a, b, c 116 FROM ... 100 117 """, (param1, param2)): 101 118 # do something with a, b, c 102 119 }}} 103 120 104 or: 105 106 {{{ 107 #!python 108 from trac.env import Environment 109 def myFunc(): 110 env = Environment('/path/to/projenv') 111 with env.db_query as db: 112 for a, b, c in db.select(""" 113 a, b, c FROM ... 114 """, (param1, param2)): 115 # do something with a, b, c 116 }}} 117 118 or even: 119 120 {{{ 121 #!python 122 from trac.env import Environment 123 def myFunc(): 124 env = Environment('/path/to/projenv') 125 for a, b, c in env.db_query.select(""" 126 a, b, c FROM ... 127 """, (param1, param2)): 128 # do something with a, b, c 129 }}} 121 These short forms also present an additional safety measure as they're only allowing a "SELECT" query to be executed by a read-only connection (indeed, the same short forms are possible on both `env.db_transaction` and `env.db_query`). 130 122 131 123 === Configuration