Revision 1869
Added by Aaron Marcuse-Kubitza over 12 years ago
sql.py | ||
---|---|---|
1 | 1 |
# Database access |
2 | 2 |
|
3 |
import copy |
|
3 | 4 |
import random |
4 | 5 |
import re |
5 | 6 |
import sys |
... | ... | |
54 | 55 |
else: raise NotImplementedError("Can't escape name for "+module+' database') |
55 | 56 |
return quote + name.replace(quote, '') + quote |
56 | 57 |
|
57 |
##### Connection object
|
|
58 |
##### Database connections
|
|
58 | 59 |
|
60 |
db_engines = { |
|
61 |
'MySQL': ('MySQLdb', {'password': 'passwd', 'database': 'db'}), |
|
62 |
'PostgreSQL': ('psycopg2', {}), |
|
63 |
} |
|
64 |
|
|
65 |
DatabaseErrors_set = set([DbException]) |
|
66 |
DatabaseErrors = tuple(DatabaseErrors_set) |
|
67 |
|
|
68 |
def _add_module(module): |
|
69 |
DatabaseErrors_set.add(module.DatabaseError) |
|
70 |
global DatabaseErrors |
|
71 |
DatabaseErrors = tuple(DatabaseErrors_set) |
|
72 |
|
|
73 |
def db_config_str(db_config): |
|
74 |
return db_config['engine']+' database '+db_config['database'] |
|
75 |
|
|
59 | 76 |
class DbConn: |
60 |
def __init__(self, db): |
|
61 |
self.db = db |
|
77 |
def __init__(self, db_config, serializable=True): |
|
78 |
self.db_config = db_config |
|
79 |
self.serializable = serializable |
|
80 |
|
|
81 |
self.__db = None |
|
62 | 82 |
self.pkeys = {} |
63 | 83 |
self.index_cols = {} |
84 |
|
|
85 |
def __getattr__(self, name): |
|
86 |
if name == '__dict__': raise Exception('getting __dict__') |
|
87 |
if name == 'db': return self._db() |
|
88 |
else: raise AttributeError() |
|
89 |
|
|
90 |
def __getstate__(self): |
|
91 |
state = copy.copy(self.__dict__) # shallow copy |
|
92 |
state['_DbConn__db'] = None # don't pickle the connection |
|
93 |
return state |
|
94 |
|
|
95 |
def _db(self): |
|
96 |
if self.__db == None: |
|
97 |
# Process db_config |
|
98 |
db_config = self.db_config.copy() # don't modify input! |
|
99 |
module_name, mappings = db_engines[db_config.pop('engine')] |
|
100 |
module = __import__(module_name) |
|
101 |
_add_module(module) |
|
102 |
for orig, new in mappings.iteritems(): |
|
103 |
try: util.rename_key(db_config, orig, new) |
|
104 |
except KeyError: pass |
|
105 |
|
|
106 |
# Connect |
|
107 |
self.__db = module.connect(**db_config) |
|
108 |
|
|
109 |
# Configure connection |
|
110 |
if self.serializable: run_raw_query(self, |
|
111 |
'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE') |
|
112 |
|
|
113 |
return self.__db |
|
64 | 114 |
|
115 |
connect = DbConn |
|
116 |
|
|
65 | 117 |
##### Querying |
66 | 118 |
|
67 | 119 |
def run_raw_query(db, query, params=None): |
... | ... | |
299 | 351 |
except StopIteration: |
300 | 352 |
if not create: raise |
301 | 353 |
return put(db, table, row, pkey, row_ct_ref) # insert new row |
302 |
|
|
303 |
##### Database connections |
|
304 |
|
|
305 |
db_engines = { |
|
306 |
'MySQL': ('MySQLdb', {'password': 'passwd', 'database': 'db'}), |
|
307 |
'PostgreSQL': ('psycopg2', {}), |
|
308 |
} |
|
309 |
|
|
310 |
DatabaseErrors_set = set([DbException]) |
|
311 |
DatabaseErrors = tuple(DatabaseErrors_set) |
|
312 |
|
|
313 |
def _add_module(module): |
|
314 |
DatabaseErrors_set.add(module.DatabaseError) |
|
315 |
global DatabaseErrors |
|
316 |
DatabaseErrors = tuple(DatabaseErrors_set) |
|
317 |
|
|
318 |
def connect(db_config, serializable=True): |
|
319 |
db_config = db_config.copy() # don't modify input! |
|
320 |
module_name, mappings = db_engines[db_config.pop('engine')] |
|
321 |
module = __import__(module_name) |
|
322 |
_add_module(module) |
|
323 |
for orig, new in mappings.iteritems(): |
|
324 |
try: util.rename_key(db_config, orig, new) |
|
325 |
except KeyError: pass |
|
326 |
db = DbConn(module.connect(**db_config)) |
|
327 |
if serializable: |
|
328 |
run_raw_query(db, 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE') |
|
329 |
return db |
|
330 |
|
|
331 |
def db_config_str(db_config): |
|
332 |
return db_config['engine']+' database '+db_config['database'] |
Also available in: Unified diff
sql.py: DbConn: Made it picklable by establishing a connection on demand