Hi i am looking for some help with an "List index out of range" error i am getting while trying to insert data into my sqlite3 database.
This is my first attempt at using a class helper to parse data to and from my database, so please don't laugh at my unwieldy coding. :))
here is my main.py for testing out my class.
import kivy
kivy.require('1.9.1')
from databaseHelper import DatabaseHelper
from kivy.app import App
from kivy.uix.widget import Widget
class Window1(Widget):
pass
class MyApp(App):
def build(self):
db = DatabaseHelper()
db.createDatabase('myDatabase')
columnData = ['unix', 'value', 'datestamp', 'keyword']
data = [57489543789, 2096, "12-12-12", "hello data"]
db.createTable(db.name, "datatable", columnData)
db.insertInto(db.name, "datatable", columnData, data)
return Window1()
if __name__ == '__main__':
MyApp().run()
Which creates the database and creates the table entries. Here is my insertInto method from my DatabaseHelper class.
def insertInto(self, db_name, table_name, column_data, data):
self.db_name = db_name
self.table_name = table_name
self.column_data = column_data
self.data = data
try:
conn = sqlite3.connect(self.db_name)
c = conn.cursor()
dataString = ''
string = ''
values = ''
for i in data:
string += column_data[i] + ", "
values += '?, '
dataString += 'self.data' + '[' + str(i) + ']' + ', '
string = string[0:string.__len__() - 2]
values = values[0:values.__len__() - 2]
dataString = dataString[0:dataString.__len__() - 2]
c.execute("INSERT INTO " + self.table_name + " (" + string + ")" + " VALUES " + "(" + values + ")",
"(" + dataString + ")"
)
conn.commit()
print("Succesfully input data into database: " + self.db_name + " Table: " + self.table_name)
except Exception as e:
print("Failed to input data into database: " + self.db_name + " Table: " + self.table_name)
print(e)
finally:
c.close()
conn.close()
Which throws an "List index out of range" error.
Any help would be much appreciated, thanks.
There is way too much string manipulation going on there. This insertInto
is probably closer to what you want:
def insertInto(self, db_name, table_name, column_data, data):
self.db_name = db_name
self.table_name = table_name
self.column_data = column_data
self.data = data
try:
conn = sqlite3.connect(self.db_name)
c = conn.cursor()
c.execute(
"INSERT INTO {table} ({columns}) VALUES ({parameters})".format(
table=table_name,
columns=', '.join(column_data),
parameters=', '.join(['?'] * len(column_data)),
),
data
)
conn.commit()
print("Succesfully input data into database: " + self.db_name + " Table: " + self.table_name)
except Exception as e:
print("Failed to input data into database: " + self.db_name + " Table: " + self.table_name)
print(e)
finally:
c.close()
conn.close()
The key changes here are:
str.join
ing all of the items instead of concatenating the next part and a delimiter in a loop, then slicing away the delimiter afterwards.
Here's how it works:
>>> ', '.join(['one', 'two', 'three']) 'one, two, three'
Using string formatting to build strings by naming parts instead of using the +
operator a bunch. It's easier to read.
Using list multiplication to get some number of ?
placeholders.
And here's how that works:
>>> ['?'] * 5 ['?', '?', '?', '?', '?']
Passing data
as a parameter instead of a string with the text '(data[0], data[1], …)'
. data
should probably be a tuple, too:
columnData = ('unix', 'value', 'datestamp', 'keyword') data = (57489543789, 2096, "12-12-12", "hello data")
I'm also not sure what a DatabaseHelper
is supposed to represent. Does it have any state associated with it? self.db_name
, self.table_name
, self.column_data
, self.data
… they all seem to get overwritten with every insertion. A database connection seems like useful state to associate with a database helper, though:
class DatabaseHelper:
def __init__(self, db_name):
self.connection = sqlite3.connect(self.db_name, isolation_level=None)
def close(self):
self.connection.close()
def insertInto(self, table_name, columns, data):
query = "INSERT INTO {table} ({columns}) VALUES ({parameters})".format(
table=table_name,
columns=', '.join(columns),
parameters=', '.join(['?'] * len(columns))
)
self.connection.execute(query, data)
print("Succesfully input data into database: " + db_name + " Table: " + table_name)
Then you can use it like this:
class MyApp(App):
def build(self):
db = DatabaseHelper('myDatabase')
columnData = ('unix', 'value', 'datestamp', 'keyword')
data = (57489543789, 2096, "12-12-12", "hello data")
db.createTable("datatable", columnData)
db.insertInto("datatable", columnData, data)
return Window1()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.