LSSTApplications  11.0-24-g0a022a1,14.0+77,15.0,15.0+1
LSSTDataManagementBasePackage
mysqlExecutor.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008, 2009, 2010 LSST Corporation.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 
23 from __future__ import with_statement
24 from __future__ import print_function
25 from contextlib import closing
26 import getpass
27 import MySQLdb as sql
28 import argparse
29 import os
30 import subprocess
31 import sys
32 from lsst.daf.persistence import DbAuth
33 
34 
36 
37  def __init__(self, host, database, user, port=3306, password=None):
38  self.host = host
39  self.port = port
40  self.user = user
41  self.database = database
42  if password is None:
43  if self.host is not None and self.port is not None and \
44  DbAuth.available(self.host, str(self.port)):
45  self.user = DbAuth.username(self.host, str(self.port))
46  password = DbAuth.password(self.host, str(self.port))
47  elif not os.path.exists(os.path.join(os.environ['HOME'], ".my.cnf")):
48  password = getpass.getpass("%s's MySQL password: " % user)
49  self.password = password
50  self.mysqlCmd = ['mysql']
51  if host is not None:
52  self.mysqlCmd += ['-h', self.host]
53  if port is not None:
54  self.mysqlCmd += ['-P', str(self.port)]
55  if user is not None:
56  self.mysqlCmd += ['-u', self.user]
57  if password is not None:
58  self.mysqlCmd += ['-p' + self.password]
59 
60  def createDb(self, database, options=['-vvv']):
61  if not isinstance(database, basestring):
62  raise TypeError('database name is not a string')
63  cmd = list(self.mysqlCmd)
64  cmd += options
65  cmd += ['-e', 'CREATE DATABASE %s;' % database]
66  subprocess.check_call(cmd, stdout=sys.stdout, stderr=sys.stderr)
67  sys.stdout.flush()
68  sys.stderr.flush()
69 
70  def execStmt(self, stmt, stdout=sys.stdout, options=['-vvv']):
71  if not isinstance(stmt, basestring):
72  raise TypeError('SQL statement is not a string')
73  cmd = list(self.mysqlCmd)
74  if self.database is not None:
75  cmd += ['-D', self.database]
76  cmd += options
77  cmd += ['-e', stmt]
78  subprocess.check_call(cmd, stdout=stdout, stderr=sys.stderr)
79  stdout.flush()
80  sys.stderr.flush()
81 
82  def execScript(self, script, options=['-vvv']):
83  if not isinstance(script, basestring):
84  raise TypeError('Script file name is not a string')
85  if not os.path.isfile(script):
86  raise RuntimeError(
87  'Script %s does not exist or is not a file' % script)
88  with open(script, 'rb') as f:
89  cmd = list(self.mysqlCmd)
90  if self.database is not None:
91  cmd += ['-D', self.database]
92  cmd += options
93  subprocess.check_call(cmd, stdin=f,
94  stdout=sys.stdout, stderr=sys.stderr)
95  sys.stdout.flush()
96  sys.stderr.flush()
97 
98  def runQuery(self, query):
99  if not isinstance(query, basestring):
100  raise TypeError('Query is not a string')
101  with closing(self.getConn()) as conn:
102  with closing(conn.cursor()) as cursor:
103  print(query)
104  sys.stdout.flush()
105  cursor.execute(query)
106  return cursor.fetchall()
107 
108  def isView(self, table):
109  with closing(self.getConn()) as conn:
110  with closing(conn.cursor()) as cursor:
111  cursor.execute('SELECT COUNT(*) FROM information_schema.tables '
112  'WHERE table_schema=%s AND table_name=%s AND '
113  'table_type=\'VIEW\'', (self.database, table))
114  return cursor.fetchone()[0] == 1
115 
116  def exists(self, table):
117  with closing(self.getConn()) as conn:
118  with closing(conn.cursor()) as cursor:
119  cursor.execute('SELECT COUNT(*) FROM information_schema.tables '
120  'WHERE table_schema=%s AND table_name=%s',
121  (self.database, table))
122  return cursor.fetchone()[0] == 1
123 
124  def getConn(self):
125  kw = dict()
126  if self.host is not None:
127  kw['host'] = self.host
128  if self.port is not None:
129  kw['port'] = self.port
130  if self.user is not None:
131  kw['user'] = self.user
132  if self.database is not None:
133  kw['db'] = self.database
134  if self.password is not None:
135  kw['passwd'] = self.password
136  return sql.connect(**kw)
137 
138 
139 def addDbOptions(parser):
140  if not isinstance(parser, argparse.ArgumentParser):
141  raise TypeError('Expecting an argparse.ArgumentParser')
142  defUser = ('USER' in os.environ and os.environ['USER']) or None
143  parser.add_argument(
144  "--user", default=defUser, dest="user",
145  help="MySQL database user name (%(default)s).")
146  parser.add_argument(
147  "--host", default="lsst10.ncsa.uiuc.edu", dest="host",
148  help="MySQL database server hostname (%(default)s).")
149  parser.add_argument(
150  "--port", default=3306, type=int, dest="port",
151  help="MySQL database server port (%(default)d).")
def createDb(self, database, options=['-vvv'])
def execScript(self, script, options=['-vvv'])
def __init__(self, host, database, user, port=3306, password=None)
def execStmt(self, stmt, stdout=sys.stdout, options=['-vvv'])