python- sqlite3.OperationalError: near ",": syntax error" - python

This isn't my code; I got it from https://www.youtube.com/channel/UC4KX0hatvRrOVy_D0nPlusg. The author didn't have the source code so I just had to type it up from the video. His worked fine but I kept getting this error:
File "D:\ProgramDevelopment\Python\Project\Python_GUI_IDEL\PythonDatabaseYoutube.py", line 45, in run_query
query_result= cursor.execute(query,parameters)
sqlite3.OperationalError: near ",": syntax error"
Link in github: https://github.com/ahmed-aya/Python_database/blob/master/Python_Database
from tkinter import *
from tkinter import ttk
import sqlite3
class Product(object):
def __init__(self,wind):
self.wind=wind
self.wind.title('IT products')
frame = LabelFrame (self.wind,text= 'Add new record')
frame.grid (row=0,column=1)
Label(frame,text='Name:').grid(row=1,column=1)
self.name =Entry(frame)
self.name.grid(row=1,column=2)
Label(frame,text='Price:').grid(row=2,column=1)
self.price =Entry(frame)
self.price.grid(row=2,column=2)
ttk.Button(frame,text='Add record',command=self.adding).grid(row=3,column=2)
self.message=Label(text='',fg='red')
self.message.grid(row=3,column=0)
self.tree=ttk.Treeview(height=10,column=2)
self.tree.grid(row=4,column=0,columnspan=2)
self.tree.heading('#0',text='Name',anchor=W)
self.tree.heading(2,text='Price',anchor=W)
ttk.Button(text='Delete record',command=self.deleting).grid(row=5,column=0)
ttk.Button(text='Edit record',command=self.editing).grid(row=5,column=1)
self.viewing_records()
def run_query (self, query, parameters=()):
with sqlite3.connect('database.db') as conn:
cursor = conn.cursor()
query_result= cursor.execute(query,parameters)
conn.commit()
return query_result
def viewing_records(self):
records = self.tree.get_children()
for element in records:
self.tree.delete(element)
query ='SELECT * FROM product ORDER BY name DESC'
db_rows = self.run_query (query)
for row in db_rows:
self.tree.insert('',0,text=row[1], values = row[2])
def validation (self):
return len (self.name.get()) !=0 and len (self.price.get()) !=0
def adding (self):
if self.validation():
query ='INSERT INTO product VALUES (NULL,?,?)'
parameters =(self.name.get(),self.price.get())
self.run_query(query,parameters)
self.message ['text'] = 'Record {} added'.format (self.name.get())
self.name.delete(0,END)
self.price.delete(0,END)
else:
self.message['text']='name field or price is empty'
self.viewing_records()
def deleting (self):
self.message['text']=''
try:
self.tree.item (self.tree.selection())['text']
except IndexError as e:
self.message['text']='Please, select recoard'
return
self.message['text']=''
name=self.tree.item (self.tree.selection())['text']
query='DELETE FROM product WHERE name=?'
self.run_query(query,(name,))
self.message['text']='Record {} deleted.'.format(name)
self.viewing_records()
def editing(self):
self.message['text']=""
try:
self.tree.item (self.tree.selection())['values'][0]
except IndexError as e:
self.message['text']='Please select record'
return
name = self.tree.item (self.tree.selection())['text']
old_price = self.tree.item (self.tree.selection())['values'][0]
self.edit_wind= Toplevel()
self.edit_wind.title('Edit Window')
Label (self.edit_wind,text='Old name: ').grid(row=0,column=1)
Entry (self.edit_wind,textvariable=StringVar(self.edit_wind,value=name),state='readonly').grid(row=0,column=2)
Label (self.edit_wind,text='New name: ').grid(row=1,column=1)
new_name = Entry(self.edit_wind)
new_name.grid(row=1,column=2)
Label (self.edit_wind,text='Old price: ').grid(row=2,column=1)
Entry (self.edit_wind,textvariable = DoubleVar(self.edit_wind,value=old_price),state='readonly').grid(row=2,column=2)
Label (self.edit_wind,text='New price: ').grid(row=3,column=1)
new_price=Entry(self.edit_wind)
new_price.grid(row=3,column=2)
Button(self.edit_wind,text='save changes', command=lambda:self.edit_records(new_name.get(),name,new_price.get(),old_price)).grid(row=4,column=2,sticky=W)
self.edit_wind.mainloop()
def edit_records(self, new_name,name,new_price,old_price):
query = 'UPDATE product SET name=?,price,=? WHERE name=? AND price =?'
parameters = (new_name,new_price,name,old_price)
self.run_query (query,parameters)
self.edit_wind.destroy()
self.message['text']='Record {} changed.'.format(name)
self.viewing_records()
if __name__== '__main__':
wind=Tk()
application = Product(wind)
wind.mainloop()

As your error says, you have a typo.
query = 'UPDATE product SET name=?,price,=? WHERE name=? AND price =?'
^ extra comma here

Related

_tkinter.TclError: wrong # args: should be ".!entry4 insert index text"

I'm trying to list all the data i got from my database using tkinter.
I'm following this post: https://www.geeksforgeeks.org/create-table-using-tkinter/
I got this erorr:
File "/Users/nobu/WorkSpace/Python/CommandLineApps/guineapig/guineapig/gui_tkinter.py", line 18, in __init__
self.entry.insert(END, result[i][j])
File "/usr/local/Cellar/python#3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py", line 3056, in insert
self.tk.call(self._w, 'insert', index, string)
_tkinter.TclError: wrong # args: should be ".!entry4 insert index text"
Here's my code:
from tkinter import *
import mysql.connector
import utils
class Table:
def __init__(self,root, result):
# code for creating table
total_rows = len(result)
total_columns = len(result[0])
for i in range(total_rows):
for j in range(total_columns):
self.e = Entry(root, width=20, fg='white')
self.e.grid(row=i, column=j)
self.e.insert(END, result[i][j]) # <- Here I got an error
def get_all():
connection, cursor = utils.connect_db()
with connection:
root = Tk()
cursor.execute("SELECT * FROM item ORDER BY item_id DESC")
result = cursor.fetchall()
if len(result) == 0:
label = Label(text="There are no items. Please create one.")
else:
table = Table(root, result)
root.mainloop()
I'm very new to tkinter. Please help me solve this issue.
Thank you #Bryan Oakley!
My list has None, so I did this:
if result[i][j] is not None:
self.entry.insert(END, result[i][j])
else:
self.entry.insert(END, "None")

Got the AttributeError: 'FarmerClass' object has no attribute 'farmer_name' in the following code

I am trying to work around autocomplete dropdown combobox which works fine with database. but when i try to fetch data after updating database in runtime I got AttributeError: 'FarmerClass' object has no attribute 'farmer_name'. I tried other available solutions but still error is not solved. as of now, typo and syntax looks fine from the reference code which i was following.
the class which throws error
class FarmerClass(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.veg = []
self.farmer = []
self.buyers = []
self.fetch_data()
self.farmer_name = ttk.Combobox(self)
self.farmer_name['values'] = self.farmer
self.farmer_name.focus()
self.farmer_name.bind('<KeyRelease>', self.check_name)
self.farmer_name.bind('<<ComboboxSelected>>', self.get_data)
self.farmer_name.place(relx=0.028, rely=0.243, width=240, height=24)
self.product = ttk.Combobox(self )
self.product['values'] = self.veg
self.product.bind('<KeyRelease>', self.check_veg)
self.product.place(relx=0.028, rely=0.380,width=240, height=24)
self.buyer = ttk.Combobox(self )
self.buyer['values'] = self.buyers
self.buyer.bind('<KeyRelease>', self.check_buyer)
self.buyer.place(relx=0.028, rely=0.5237,width=240, height=24)
#======================= Entry btn ====================
self.entry_btn = tk.Button(self,Btn_base, text='Entry', command=self.entry_to_bill)
self.entry_btn.place(relx=0.481, rely=0.525,width=134, height=24)
def fetch_data(self, event=None):
cur.execute('SELECT * FROM vegetable ')
for i in cur.fetchall():
self.veg.append(i[0])
cur.execute('SELECT rowid, * FROM farmers ')
for i in cur.fetchall():
self.farmer.append(i[2])
cur.execute('SELECT rowid,name FROM buyers_avail ')
for i in cur.fetchall():
self.buyers.append(i[1])
self.farmer_name.configure(values= self.farmer) # getting error here
self.product.configure(values= self.veg)
self.buyer.configure(values= self.buyers)
def entry_to_bill(self, event=None):
name = self.buyer.get().lower()
cur.execute('SELECT name FROM buyers_avail WHERE name = ? ', [name])
bnames = cur.fetchall()
if bnames:
print(f'buyer {bnames} found')
else:
cur.execute('INSERT INTO buyers_avail (name) VALUES (?)',[name,])
db.commit()
self.buyer.delete(0, tk.END)
self.buyer.focus()
self.fetch_data()
if i try without those lines, farmer_name looks fine, product gets values of buyers and buyer dropdown goes empty.
please ask if anything required related to question.
The fetch_data function accesses farmer_name but you call it before defining farmer_name, which therefore doesn't exist at that point. You need to call fetch_data after defining farmer_name.

QSqlTableModel.setData error but lastError() always empty

you're help is needed:
the mystery is located in Method setupNumRibs.
In my test setup the table contains only one row.
res = self.setData(self.index(0, 1), numRows )
Executes and does the table update as expected.
res = self.setData(self.index(1, 1), numRows )
Must fail, as the row to be updated does not exist.
res is FALS as expected, BUT on the cmd line I get:
model ErrT : 0
model Err text : ||
db ErrT : 0
db Err text : ||
Somwhow the
modelError = self.lastError()
Fails, I don't get the correct info back, but I don't see WHY :-(
The full code:
from Singleton.Singleton import Singleton
class ProcessorModel(QSqlTableModel, metaclass=Singleton):
def __init__(self, parent=None):
self.fileNamePath = ''
self.fileVersion = ''
# open database
self.db = QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("processorModel.sqlite")
if not self.db.open():
logging.error(self.__className+ '.__init__ cannot open db')
super().__init__()
# make sure tables are there
self.rib_M = self.RibModel()
self.wing_M = self.WingModel()
def isValid( self, fileName ):
def setFileName( self, fileName ):
def openFile(self):
def readFile(self):
def remTabSpace(self, line):
def remTabSpaceQuot(self, line):
class WingModel(QSqlTableModel, metaclass=Singleton):
def createWingTable(self):
def __init__(self, parent=None):
def syncData(self, q):
class RibModel(QSqlTableModel, metaclass=Singleton):
__className = 'RibModel'
RibNumCol = 1
xribCol = 2
yLECol = 3
yTECol = 4
xpCol = 5
zCol = 6
betaCol = 7
RPCol = 8
WashinCol = 9
def createRibTable(self):
logging.debug(self.__className+'.createRibTable')
query = QSqlQuery()
query.exec("DROP TABLE if exists Rib;")
query.exec("create table if not exists Rib ("
"ID INT PRIMARY KEY,"
"RibNum varchar(50),"
"xrib varchar(50),"
"yLE varchar(50),"
"yTE varchar(50),"
"xp varchar(50),"
"z varchar(50),"
"beta varchar(50),"
"RP varchar(50),"
"Washin varchar(50));")
query.exec("INSERT into Rib (ID) Values( '1' );")
def __init__(self, parent=None):
'''
:method: Constructor
'''
super().__init__()
self.createRibTable()
self.setTable("Rib")
self.select()
self.setEditStrategy(QSqlTableModel.OnFieldChange)
def setupNumRibs(self, halfNumRibs):
logging.debug(self.__className+'.setupNumRibs')
numRows = self.rowCount()
res = self.setData(self.index(1, 1), numRows )
if not res:
modelError = self.lastError()
print('model ErrT : %s' %modelError.type())
print('model Err text : |%s|' %modelError.text())
print()
procM = ProcessorModel()
dbError = procM.db.lastError()
print('db ErrT : %s' %dbError.type())
print('db Err text : |%s|' %dbError.text())
print()
The Singleton Class can be found already here
There is no mystery if you read the docs:
QSqlError QSqlQueryModel::lastError() const
Returns information about the last error that occurred on the
database.
It is clearly indicated that lastError() indicates an error that happens when interacting with the database, but in your case it does not interact since the model first verifies that the QModelIndex is valid, and since yours is not valid then it returns immediately false without doing any transaction with the database.
On the other hand, don't complicate your problem by adding Singleton or other elements that are just noise. It would be recommended that for each question you create an MRE focused only on the problem and thus save us time to help you instead of having to eliminate silly code.

Django Queryset returns None, but the inner query works correctly

I've got a QuerySet that's behaving a little strangely. When I run the self.get() section individually and print the results (i.e. pr), it correctly returns the PriceRange object. When I return the same value, it's None.
class PriceRangeQuerySet(QuerySet):
def get_price_range(self, price):
try:
pr = self.get(
(Q(bottom__isnull = True) | Q(bottom__lt = price)) & \
(Q(top__isnull = True) | Q(top__gte = price))
)
return pr
except PriceRange.DoesNotExist:
mail_admins("Price range not found", 'Price: %d' % price)
except PriceRange.MultipleObjectsReturned:
mail_admins("Multiple matching price ranges found", 'Price: %d' % price)

Error message "MemoryError" in Python

Here's my problem: I'm trying to parse a big text file (about 15,000 KB) and write it to a MySQL database. I'm using Python 2.6, and the script parses about half the file and adds it to the database before freezing up. Sometimes it displays the text:
MemoryError.
Other times it simply freezes. I figured I could avoid this problem by using generator's wherever possible, but I was apparently wrong.
What am I doing wrong?
When I press Ctrl + C to keyboard interrupt, it shows this error message:
...
sucessfully added vote # 2281
sucessfully added vote # 2282
sucessfully added vote # 2283
sucessfully added vote # 2284
floorvotes_db.py:35: Warning: Data truncated for column 'vote_value' at row 1
r['bill ID'] , r['last name'], r['vote'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "floorvotes_db.py", line 67, in addAllFiles
addFile(file)
File "floorvotes_db.py", line 61, in addFile
add(record)
File "floorvotes_db.py", line 35, in add
r['bill ID'] , r['last name'], r['vote'])
File "build/bdist.linux-i686/egg/MySQLdb/cursors.py", line 166, in execute
File "build/bdist.linux-i686/egg/MySQLdb/connections.py", line 35, in defaulte rrorhandler
KeyboardInterrupt
import os, re, datetime, string
# Data
DIR = '/mydir'
tfn = r'C:\Documents and Settings\Owner\Desktop\data.txt'
rgxs = {
'bill number': {
'rgx': r'(A|S)[0-9]+-?[A-Za-z]* {50}'}
}
# Compile rgxs for speediness
for rgx in rgxs: rgxs[rgx]['rgx'] = re.compile(rgxs[rgx]['rgx'])
splitter = rgxs['bill number']['rgx']
# Guts
class floor_vote_file:
def __init__(self, fn):
self.iterdata = (str for str in
splitter.split(open(fn).read())
if str and str <> 'A' and str <> 'S')
def iterVotes(self):
for record in self.data:
if record: yield billvote(record)
class billvote(object):
def __init__(self, section):
self.data = [line.strip() for line
in section.splitlines()]
self.summary = self.data[1].split()
self.vtlines = self.data[2:]
self.date = self.date()
self.year = self.year()
self.votes = self.parse_votes()
self.record = self.record()
# Parse summary date
def date(self):
d = [int(str) for str in self.summary[0].split('/')]
return datetime.date(d[2],d[0],d[1]).toordinal()
def year(self):
return datetime.date.fromordinal(self.date).year
def session(self):
"""
arg: 2-digit year int
returns: 4-digit session
"""
def odd():
return divmod(self.year, 2)[1] == 1
if odd():
return str(string.zfill(self.year, 2)) + \
str(string.zfill(self.year + 1, 2))
else:
return str(string.zfill(self.year - 1, 2))+ \
str(string.zfill(self.year, 2))
def house(self):
if self.summary[2] == 'Assembly': return 1
if self.summary[2] == 'Senate' : return 2
def splt_v_line(self, line):
return [string for string in line.split(' ')
if string <> '']
def splt_v(self, line):
return line.split()
def prse_v(self, item):
"""takes split_vote item"""
return {
'vote' : unicode(item[0]),
'last name': unicode(' '.join(item[1:]))
}
# Parse votes - main
def parse_votes(self):
nested = [[self.prse_v(self.splt_v(vote))
for vote in self.splt_v_line(line)]
for line in self.vtlines]
flattened = []
for lst in nested:
for dct in lst:
flattened.append(dct)
return flattened
# Useful data objects
def record(self):
return {
'date' : unicode(self.date),
'year' : unicode(self.year),
'session' : unicode(self.session()),
'house' : unicode(self.house()),
'bill ID' : unicode(self.summary[1]),
'ayes' : unicode(self.summary[5]),
'nays' : unicode(self.summary[7]),
}
def iterRecords(self):
for vote in self.votes:
r = self.record.copy()
r['vote'] = vote['vote']
r['last name'] = vote['last name']
yield r
test = floor_vote_file(tfn)
import MySQLdb as dbapi2
import floorvotes_parse as v
import os
# Initial database crap
db = dbapi2.connect(db=r"db",
user="user",
passwd="XXXXX")
cur = db.cursor()
if db and cur: print "\nConnected to db.\n"
def commit(): db.commit()
def ext():
cur.close()
db.close()
print "\nConnection closed.\n"
# DATA
DIR = '/mydir'
files = [DIR+fn for fn in os.listdir(DIR)
if fn.startswith('fvote')]
# Add stuff
def add(r):
"""add a record"""
cur.execute(
u'''INSERT INTO ny_votes (vote_house, vote_date, vote_year, bill_id,
member_lastname, vote_value) VALUES
(%s , %s , %s ,
%s , %s , %s )''',
(r['house'] , r['date'] , r['year'],
r['bill ID'] , r['last name'], r['vote'])
)
#print "added", r['year'], r['bill ID']
def crt():
"""create table"""
SQL = """
CREATE TABLE ny_votes (openleg_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
vote_house int(1), vote_date int(5), vote_year int(2), bill_id varchar(8),
member_lastname varchar(50), vote_value varchar(10));
"""
cur.execute(SQL)
print "\nCreate ny_votes.\n"
def rst():
SQL = """DROP TABLE ny_votes"""
cur.execute(SQL)
print "\nDropped ny_votes.\n"
crt()
def addFile(fn):
"""parse and add all records in a file"""
n = 0
for votes in v.floor_vote_file(fn).iterVotes():
for record in votes.iterRecords():
add(record)
n += 1
print 'sucessfully added vote # ' + str(n)
def addAllFiles():
for file in files:
addFile(file)
if __name__=='__main__':
rst()
addAllFiles()
Generators are a good idea, but you seem to miss the biggest problem:
(str for str in splitter.split(open(fn).read()) if str and str <> 'A' and str <> 'S')
You're reading the whole file in at once even if you only need to work with bits at a time. You're code is too complicated for me to fix, but you should be able to use file's iterator for your task:
(line for line in open(fn))
I noticed that you use a lot of slit() calls. This is memory consuming, according to http://mail.python.org/pipermail/python-bugs-list/2006-January/031571.html . You can start investigating this.
Try to comment out add(record) to see if the problem is in your code or on the database side. All the records are added in one transaction (if supported) and maybe this leads to a problem if it get too many records. If commenting out add(record) helps, you could try to call commit() from time to time.
This isn't a Python memory issue, but perhaps it's worth thinking about. The previous answers make me think you'll sort that issue out quickly.
I wonder about the rollback logs in MySQL. If a single transaction is too large, perhaps you can checkpoint chunks. Commit each chunk separately instead of trying to rollback a 15MB file's worth.

Categories