forked from plazar/Ratings2.0
-
Notifications
You must be signed in to change notification settings - Fork 0
/
database.py
executable file
·150 lines (125 loc) · 4.18 KB
/
database.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python
import sys
import warnings
import traceback
import cmd
import prettytable
import pyodbc
from ratings2 import config
# Connecting from Linux
DATABASES = {
'common': {
'DATABASE': 'palfa-common',
'UID': config.username,
'PWD': config.password,
'HOST': config.host,
'DSN': 'FreeTDSDSN'
},
'common2': {
'DATABASE': 'palfaCandDB2',
'UID': config.username,
'PWD': config.password,
'HOST': config.host,
'DSN': 'FreeTDSDSN'
},
'common-copy': {
'DATABASE': 'palfa-common-copy',
'UID': config.username,
'PWD': config.password,
'HOST': config.host,
'DSN': 'FreeTDSDSN'
},
'tracking': {
'DATABASE': 'palfatracking',
'UID': config.username,
'PWD': config.password,
'HOST': config.host,
'DSN': 'FreeTDSDSN'
},
}
# Set defaults
DEFAULTDB = 'common-copy'
DATABASES['default'] = DATABASES[DEFAULTDB]
class Database:
"""Database object for connecting to databases using pyodbc.
"""
def __init__(self, db="default", autocommit=True):
"""Constructor for Database object.
Input:
'db': database to connect to. (Default: 'default')
(gets passed to 'self.connect')
'autocommit': boolean, determines if autocommit should
be turned on or off.
"""
self.db = db
self.connect(db, autocommit=autocommit)
def connect(self, db="default", autocommit=True):
"""Establish a database connection. Set self.conn and self.cursor.
Input:
'db': databse to connect to. Must be a key in module's
DATABASES dict. (Default: 'default')
'autocommit': boolean, determines if autocommit should
be turned on or off.
Output:
None
"""
if db not in DATABASES:
warnings.warn("Database (%s) not recognized. Using default (%s)." \
% (db, DEFAULTDB))
db = 'default'
try:
self.conn = pyodbc.connect(autocommit=autocommit, **DATABASES[db])
self.cursor = self.conn.cursor()
except:
msg = "Could not establish database connection.\n"
msg += "\tCheck your connection options:\n"
for key, val in DATABASES[db].iteritems():
msg += "\t\t%s: %s\n" % (key, val)
raise DatabaseConnectionError(msg)
def execute(self, query, *args, **kwargs):
try:
self.cursor.execute(query.encode('ascii'), *args, **kwargs)
except Exception, e:
if "has been chosen as the deadlock victim. Rerun the transaction." in str(e):
raise DatabaseDeadlockError(e)
else:
raise
def executemany(self, query, *args, **kwargs):
try:
self.cursor.executemany(query.encode('ascii'), *args, **kwargs)
except Exception, e:
if "has been chosen as the deadlock victim. Rerun the transaction." in str(e):
raise DatabaseDeadlockError(e)
else:
raise
def commit(self):
self.conn.commit()
def rollback(self):
self.conn.rollback()
def close(self):
"""Close database connection.
"""
try:
self.conn.close()
except ProgrammingError:
# database connection is already closed
pass
def fetchall(self):
return self.cursor.fetchall()
def showall(self):
desc = self.cursor.description
if desc is not None:
fields = [d[0] for d in desc]
table = prettytable.PrettyTable(fields)
for row in self.cursor:
table.add_row(row)
table.printt()
def insert(self, query):
self.cursor.execute(query)
self.commit()
class DatabaseError(Exception):
pass
class DatabaseConnectionError(DatabaseError):
pass
class DatabaseDeadlockError(DatabaseError):
pass