1 """@namespace IMP.em2d.Database
2 Utility functions to manage SQL databases with sqlite3.
5 import sqlite3
as sqlite
10 log = logging.getLogger(
"Database")
14 """ Class to manage a SQL database built with sqlite3 """
18 self.connection =
None
23 def create(self,filename,overwrite=False):
24 """ Creates a database by simply connecting to the file """
25 log.info(
"Creating database")
26 if overwrite
and os.path.exists(filename):
28 sqlite.connect(filename)
31 """ Connects to the database in filename """
32 if not os.path.isfile(filename):
33 raise IOError,
"Database file not found: %s" % filename
34 self.connection = sqlite.connect(filename)
35 self.cursor = self.connection.cursor()
38 """ Checks if the class is connected to the database filename """
39 if self.connection ==
None:
40 raise ValueError,
"The database has not been created " \
41 "or connection not established "
44 """ Creates a table. It expects a sorted dictionary
45 of (data_field,typename) entries """
46 log.info(
"Creating table %s",table_name)
48 sql_command =
"CREATE TABLE %s (" % (table_name)
49 for name, data_type
in zip(column_names, column_types):
50 sql_typename = get_sql_type_name(data_type)
51 sql_command +=
"%s %s," % (name, sql_typename)
54 sql_command = sql_command[0:n-1] +
")"
55 log.debug(sql_command)
56 self.cursor.execute(sql_command)
57 self.connection.commit()
61 Delete a table if it exists
63 log.info(
"Deleting table %s",table_name)
65 sql_command =
"DROP TABLE IF EXISTS %s" % (table_name)
66 log.debug(sql_command)
67 self.cursor.execute(sql_command)
68 self.connection.commit()
71 """ Inserts information in a given table of the database.
72 The info must be a list of tuples containing as many values
73 as columns in the table
74 Conversion of values is done AUTOMATICALLY after checking the
75 types stored in the table
79 tuple_format=
"("+
"?,"*(n-1)+
"?)"
80 sql_command=
"INSERT INTO %s VALUES %s " % (table_name, tuple_format)
87 y = [apply_type(i)
for i,apply_type
in zip(x, types)]
88 self.cursor.execute(sql_command, y)
89 self.connection.commit()
92 """ Inserts information in a given table of the database.
93 The info must be a list of tuples containing as many values
94 as columns in the table
95 Conversion of values is done AUTOMATICALLY after checking the
96 types stored in the table
99 log.warning(
"Inserting empty data")
103 tuple_format=
"("+
"?,"*(n-1)+
"?)"
104 sql_command=
"INSERT INTO %s VALUES %s " % (table_name, tuple_format)
108 for i
in xrange(len(data)):
109 data[i] = [apply_type(d)
for d,apply_type
in zip(data[i], types)]
110 self.cursor.executemany(sql_command, data)
111 self.connection.commit()
114 """ Retrieves data from the database using the sql_command
115 returns the records as a list of tuples"""
117 log.debug(
"Retrieving data: %s" % sql_command)
118 self.cursor.execute(sql_command)
119 return self.cursor.fetchall()
126 """ updates the register in the table identified by the condition
127 values for the condition fields
130 sql_command =
"UPDATE %s SET " % (table_name)
131 for field, value
in zip(updated_fields, updated_values):
132 sql_command +=
"%s=%s," % (field, value)
133 sql_command = sql_command.rstrip(
",") +
" WHERE "
135 sql_command = sql_command + s
137 log.debug(
"Updating %s: %s",table_name, sql_command)
138 self.cursor.execute(sql_command)
139 self.connection.commit()
142 condition_fields, condition_values):
143 """ creates a view of the given table where the values are selected
144 using the condition values. See the help for update_data()
150 sql_command =
'CREATE VIEW %s AS SELECT * FROM %s WHERE ' % (view_name, table_name)
152 sql_command += condition
153 log.info(
"Creating view %s", sql_command)
154 self.cursor.execute(sql_command)
156 def create_view_of_best_records(self, view_name, table_name, orderby, n_records):
161 sql_command =
"""CREATE VIEW %s AS SELECT * FROM %s
162 ORDER BY %s ASC LIMIT %d """ % (view_name, table_name, orderby, n_records)
163 log.info(
"Creating view %s", sql_command)
164 self.cursor.execute(sql_command)
167 """ Removes a view from the database """
168 self.cursor.execute(
'DROP VIEW %s' % view_name)
170 def get_table(self, table_name, fields=False, orderby=False):
171 """ Returns th fields requested from the table """
172 fields = self.get_fields_string(fields)
173 sql_command =
"SELECT %s FROM %s " % (fields, table_name)
175 sql_command +=
" ORDER BY %s ASC" % orderby
179 def get_fields_string(self, fields, field_delim=","):
181 return field_delim.join(fields)
185 """ Closes the database """
188 self.connection.close()
191 """ creates a condition applying each value to each field
194 for field,value
in zip(fields,values):
195 s +=
"%s=%s AND " % (field, value)
203 Gets info about a table and retuns all the types in it
206 sql_command =
"PRAGMA table_info(%s)" % name
207 self.cursor.execute(sql_command)
208 info = self.cursor.fetchall()
213 elif row[2] ==
"DOUBLE":
215 elif row[2][0:7] ==
"VARCHAR":
221 Get the names of the columns for a given table
224 sql_command =
"PRAGMA table_info(%s)" % name
225 self.cursor.execute(sql_command)
226 info = self.cursor.fetchall()
227 return [ row[1]
for row
in info]
229 def execute_sql_command(self, sql_command):
231 self.cursor.execute(sql_command)
232 self.connection.commit()
237 Add a column to a table
238 column - the name of the column.
239 data_type - the type: int, float, str
241 sql_typename = get_sql_type_name(data_type)
242 sql_command =
"ALTER TABLE %s ADD %s %s" % (table, column, sql_typename)
243 self.execute_sql_command(sql_command)
247 Add columns to the database. If check=True, columns with names
248 already in the database are skipped. If check=False no check
249 is done and trying to add a column that already exists will
254 for name, dtype
in zip(names, types):
255 if name
not in col_names:
258 for name, dtype
in zip(names, types):
261 def get_tables_names(self):
262 sql_command =
""" SELECT tbl_name FROM sqlite_master """
264 names = [d[0]
for d
in data]
270 Prompt for tables so the user can choose one
274 tables = self.get_tables_names()
277 while say
not in (
'n',
'y'):
278 say = raw_input(
"Use table %s (y/n) " % t)
283 return table_name, columns
286 def drop_columns(self, table, columns):
291 names_txt =
", ".join(cnames)
293 "CREATE TEMPORARY TABLE backup(%s);" % names_txt,
294 "INSERT INTO backup SELECT %s FROM %s" % (names_txt, table),
295 "DROP TABLE %s;" % table,
296 "CREATE TABLE %s(%s);" % (table, names_txt),
297 "INSERT INTO %s SELECT * FROM backup;" % table,
298 "DROP TABLE backup;",
300 for command
in sql_command:
303 self.cursor.execute(command)
306 """ Prints the data recovered from a database """
308 line = delimiter.join([str(x)
for x
in row])
312 """writes data to a file. The output file is expected to be a python
314 w = csv.writer(output_file, delimiter=delimiter)
318 def get_sql_type_name(data_type):
319 if(data_type == int):
321 elif(data_type == float):
323 elif(data_type == str):
326 def open(fn_database):
328 db.connect(fn_database)
331 def read_data(fn_database, sql_command):
333 db.connect(fn_database)
334 data = db.retrieve_data(sql_command)
339 """ Return indices that sort the list l """
340 pairs = [(element, i)
for i,element
in enumerate(l)]
342 indices = [p[1]
for p
in pairs]
347 Reads a table from a set of database files into a single file
348 Makes sure to reorder all column names if neccesary before merging
353 names = db.get_table_column_names(tbl)
354 types = db.get_table_types(tbl)
356 sorted_names = [ names[i]
for i
in indices]
357 sorted_types = [ types[i]
for i
in indices]
358 log.info(
"Merging databases. Saving to %s", fn_output)
360 out_db.create(fn_output, overwrite=
True)
361 out_db.connect(fn_output)
362 out_db.create_table(tbl, sorted_names, sorted_types)
364 log.debug(
"Reading %s",fn)
366 names = db.get_table_column_names(tbl)
368 they_are_sorted =
",".join(names)
369 log.debug(
"Retrieving %s", they_are_sorted)
370 sql_command =
"SELECT %s FROM %s" % (they_are_sorted, tbl)
371 data = db.retrieve_data(sql_command)
372 out_db.store_data(tbl, data)
def connect
Connects to the database in filename.
def check_if_is_connected
Checks if the class is connected to the database filename.
def store_dataV1
Inserts information in a given table of the database.
def get_table
Returns th fields requested from the table.
def select_table
Prompt for tables so the user can choose one.
def write_data
writes data to a file.
def store_data
Inserts information in a given table of the database.
def get_condition_string
creates a condition applying each value to each field
def merge_databases
Reads a table from a set of database files into a single file Makes sure to reorder all column names ...
def drop_view
Removes a view from the database.
def add_column
Add a column to a table column - the name of the column.
def retrieve_data
Retrieves data from the database using the sql_command returns the records as a list of tuples...
def get_table_column_names
Get the names of the columns for a given table.
def update_data
updates the register in the table identified by the condition values for the condition fields ...
def print_data
Prints the data recovered from a database.
def add_columns
Add columns to the database.
def drop_table
Delete a table if it exists.
def close
Closes the database.
def get_sorting_indices
Return indices that sort the list l.
Class to manage a SQL database built with sqlite3.
def create_table
Creates a table.
def create_view
creates a view of the given table where the values are selected using the condition values...
def create
Creates a database by simply connecting to the file.
def get_table_types
Gets info about a table and retuns all the types in it.