/
setupdb_app.py
executable file
·171 lines (139 loc) · 5.19 KB
/
setupdb_app.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#! /usr/bin/env python
"""
Create, prepare and load schema for Socorro PostgreSQL database.
"""
import sys
import psycopg2
import psycopg2.extensions
from psycopg2 import ProgrammingError
import re
import logging
from socorro.app.generic_app import App, main
from configman import Namespace
class PostgreSQLManager(object):
def __init__(self, dsn, logger):
self.conn = psycopg2.connect(dsn)
self.conn.set_isolation_level(
psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
self.logger = logger
def execute(self, sql, allowable_errors=None):
cur = self.conn.cursor()
try:
cur.execute(sql)
except ProgrammingError, e:
if not allowable_errors:
raise
dberr = e.pgerror.strip().split('ERROR: ')[1]
if allowable_errors:
for err in allowable_errors:
if re.match(err, dberr):
self.logger.warning(dberr)
else:
raise
def __enter__(self):
return self
def __exit__(self, *exc_info):
self.conn.close()
class SocorroDB(App):
app_name = 'setupdb'
app_version = '0.2'
app_description = __doc__
required_config = Namespace()
required_config.add_option(
name='database_name',
default='',
doc='Name of database to manage',
)
required_config.add_option(
name='database_hostname',
default='',
doc='Hostname to connect to database',
)
required_config.add_option(
name='database_username',
default='',
doc='Username to connect to database',
)
required_config.add_option(
name='database_password',
default='',
doc='Password to connect to database',
)
required_config.add_option(
name='database_port',
default='',
doc='Port to connect to database',
)
required_config.add_option(
name='dropdb',
default=False,
doc='Whether or not to drop database_name',
exclude_from_print_conf=True,
exclude_from_dump_conf=True
)
required_config.add_option(
name='no_schema',
default=False,
doc='Whether or not to load schema',
exclude_from_print_conf=True,
exclude_from_dump_conf=True
)
required_config.add_option(
name='citext',
default='/usr/share/postgresql/9.0/contrib/citext.sql',
doc='Name of citext.sql file',
)
def main(self):
self.database_name = self.config['database_name']
if not self.database_name:
print "Syntax error: --database_name required"
return 1
self.no_schema = self.config.get('no_schema')
self.citext = self.config.get('citext')
dsn_template = 'dbname=%s'
self.database_username = self.config.get('database_username')
if self.database_username:
dsn_template += ' user=%s' % self.database_username
self.database_password = self.config.get('database_password')
if self.database_password:
dsn_template += ' password=%s' % self.database_password
self.database_hostname = self.config.get('database_hostname')
if self.database_hostname:
dsn_template += ' host=%s' % self.database_hostname
self.database_port = self.config.get('database_port')
if self.database_port:
dsn_template += ' port=%s' % self.database_port
dsn = dsn_template % 'template1'
with PostgreSQLManager(dsn, self.config.logger) as db:
if self.config.get('dropdb'):
if 'test' not in self.database_name:
confirm = raw_input(
'drop database %s [y/N]: ' % self.database_name)
if not confirm == "y":
logging.warn('NOT dropping table')
return 2
db.execute('DROP DATABASE %s' % self.database_name,
['database "%s" does not exist' % self.database_name])
db.execute('DROP SCHEMA pgx_diag', ['schema "pgx_diag" does not exist'])
db.execute('CREATE DATABASE %s' % self.database_name,
['database "%s" already exists' % self.database_name])
dsn = dsn_template % self.database_name
with PostgreSQLManager(dsn, self.config.logger) as db:
with open('sql/roles.sql') as f:
db.execute(f.read())
for lang in ['plpgsql', 'plperl']:
db.execute('CREATE LANGUAGE "%s"' % lang,
['language "%s" already exists' % lang])
if not self.no_schema:
with open('sql/schema.sql') as f:
db.execute(f.read(), ['schema "pgx_diag" already exists'])
db.execute('SELECT weekly_report_partitions()')
else:
with open(self.citext) as f:
db.execute(f.read())
db.execute(
'ALTER DATABASE %s OWNER TO breakpad_rw' %
self.database_name)
return 0
if __name__ == '__main__': # pragma: no cover
sys.exit(main(SocorroDB))