]>
git.ipfire.org Git - ipfire.org.git/blob - src/backend/database.py
4 A lightweight wrapper around psycopg2.
6 Originally part of the Tornado framework. The tornado.database module
7 is slated for removal in Tornado 3.0, and it is now available separately
11 from __future__
import absolute_import
, division
, with_statement
20 class Connection(object):
22 A lightweight wrapper around MySQLdb DB-API connections.
24 The main value we provide is wrapping rows in a dict/object so that
25 columns can be accessed by name. Typical usage::
27 db = torndb.Connection("localhost", "mydatabase")
28 for article in db.query("SELECT * FROM articles"):
31 Cursors are hidden by the implementation, but other than that, the methods
32 are very similar to the DB-API.
34 We explicitly set the timezone to UTC and the character encoding to
35 UTF-8 on all connections to avoid time zone and encoding errors.
37 def __init__(self
, host
, database
, user
=None, password
=None):
39 self
.database
= database
44 "database" : database
,
46 "password" : password
,
52 logging
.error("Cannot connect to database on %s", self
.host
, exc_info
=True)
59 Closes this database connection.
61 if getattr(self
, "_db", None) is not None:
67 Closes the existing database connection and re-opens it.
71 self
._db
= psycopg2
.connect(**self
._db
_args
)
72 self
._db
.autocommit
= True
74 # Initialize the timezone setting.
75 self
.execute("SET TIMEZONE TO 'UTC'")
77 def query(self
, query
, *parameters
, **kwparameters
):
79 Returns a row list for the given query and parameters.
81 cursor
= self
._cursor
()
83 self
._execute
(cursor
, query
, parameters
, kwparameters
)
84 column_names
= [d
[0] for d
in cursor
.description
]
85 return [Row(itertools
.izip(column_names
, row
)) for row
in cursor
]
89 def get(self
, query
, *parameters
, **kwparameters
):
91 Returns the first row returned for the given query.
93 rows
= self
.query(query
, *parameters
, **kwparameters
)
97 raise Exception("Multiple rows returned for Database.get() query")
101 def execute(self
, query
, *parameters
, **kwparameters
):
103 Executes the given query, returning the lastrowid from the query.
105 return self
.execute_lastrowid(query
, *parameters
, **kwparameters
)
107 def execute_lastrowid(self
, query
, *parameters
, **kwparameters
):
109 Executes the given query, returning the lastrowid from the query.
111 cursor
= self
._cursor
()
113 self
._execute
(cursor
, query
, parameters
, kwparameters
)
114 return cursor
.lastrowid
118 def execute_rowcount(self
, query
, *parameters
, **kwparameters
):
120 Executes the given query, returning the rowcount from the query.
122 cursor
= self
._cursor
()
124 self
._execute
(cursor
, query
, parameters
, kwparameters
)
125 return cursor
.rowcount
129 def executemany(self
, query
, parameters
):
131 Executes the given query against all the given param sequences.
133 We return the lastrowid from the query.
135 return self
.executemany_lastrowid(query
, parameters
)
137 def executemany_lastrowid(self
, query
, parameters
):
139 Executes the given query against all the given param sequences.
141 We return the lastrowid from the query.
143 cursor
= self
._cursor
()
145 cursor
.executemany(query
, parameters
)
146 return cursor
.lastrowid
150 def executemany_rowcount(self
, query
, parameters
):
152 Executes the given query against all the given param sequences.
154 We return the rowcount from the query.
156 cursor
= self
._cursor
()
159 cursor
.executemany(query
, parameters
)
160 return cursor
.rowcount
164 def _ensure_connected(self
):
166 logging
.warning("Database connection was lost...")
171 self
._ensure
_connected
()
172 return self
._db
.cursor()
174 def _execute(self
, cursor
, query
, parameters
, kwparameters
):
175 logging
.debug("SQL Query: %s" % (query
% (kwparameters
or parameters
)))
178 return cursor
.execute(query
, kwparameters
or parameters
)
179 except (OperationalError
, psycopg2
.ProgrammingError
):
180 logging
.error("Error connecting to database on %s", self
.host
)
184 def transaction(self
):
185 return Transaction(self
)
189 """A dict that allows for object-like property access syntax."""
190 def __getattr__(self
, name
):
194 raise AttributeError(name
)
197 class Transaction(object):
198 def __init__(self
, db
):
201 self
.db
.execute("START TRANSACTION")
206 def __exit__(self
, exctype
, excvalue
, traceback
):
207 if exctype
is not None:
208 self
.db
.execute("ROLLBACK")
210 self
.db
.execute("COMMIT")
213 # Alias some common exceptions
214 IntegrityError
= psycopg2
.IntegrityError
215 OperationalError
= psycopg2
.OperationalError