SQLite error in Python - python

I have a simple piece of code to update a row in sqlite:
def UpdateElement(new_user,new_topic):
querycurs.execute('''INSERT into First_Data (topic) values(?) WHERE user = (?)''',([new_topic], [new_user]))
However, this gives me the error:
Traceback (most recent call last):
File "C:/Python27/Database.py", line 40, in <module>
UpdateElement("Abhishek Mitra","Particle Physics")
File "C:/Python27/Database.py", line 36, in UpdateElement
querycurs.execute('''INSERT into First_Data (topic) values(?) WHERE user = (?)''',([new_topic],[new_user]))
OperationalError: near "WHERE": syntax error

You should be using an UPDATE statement instead of INSERT:
def UpdateElement(new_user,new_topic):
querycurs.execute('''UPDATE First_Data
SET topic = ?
WHERE user = ?''', (new_topic, new_user))

The problem arises from the use of the parentheses and sending in new_user as an array, I believe. Values is an array, user is not.
You want something like:
cur.execute("UPDATE table SET value=? WHERE name=?", (myvalue, myname))
But yes, UPDATE sounds like what you wanted in the first place.

Related

How Can My sqllite3 interaction be fixed?

I'm trying to get an admin account to edit a 'rank' (basically access level) for one of the profiles in my data-base. The error is:
Traceback (most recent call last):
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 154, in <module>
main()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 9, in main
start_menu()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 22, in start_menu
login()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 72, in login
Mek_menu()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 108, in Mek_menu
where Uzaname = %s""" % (NewRank, Findaname))
sqlite3.OperationalError: unrecognized token: "0rk_D4T4B453"`
The code that seems to be the problem is:
cursor.execute(""" update 0rk_D4T4B453.Da_Boyz
set Rank = %s
where Uzaname = %s""" % (NewRank, Findaname))
Originally, it was all on one line and it didn't work, and now I've tried it on multiple lines and it still doesn't work. So I checked here to see if anyone could help.
EDIT1: Thanks for the suggestions. None of them have fixed the code, but I've narrowed the problem code to: where Uzaname = %s""" % (NewRank, Findaname))
Unless you use ATTACH, SQLite (a file-level database) does not recognize other databases. Usually server-level databases (Oracle, Postgres, SQL Server, etc.) use the database.schema.table reference. However, in SQLite the very database file you connect to is the main database in scope. But ATTACH allows you to connect to other SQLite databases and then recognizes database.table referencing.
Additionally, for best practices:
In sqlite3 and any other Python DB-APIs, use parameterization for literal values and do not format values to SQL statement.
In general Python, stop using the de-emphasized (not deprecated yet) string modulo operator, %. Use str.format or more recent F-string for string formatting. But neither is needed here.
Altogether, if you connect to the 0rk_D4T4B453 database, simply query without database reference:
conn = sqlite3.connect('/path/to/0rk_D4T4B453.db')
cursor = conn.cursor()
# PREPARED STATEMENT WITH QMARK PLACEHOLDERS
sql = """UPDATE Da_Boyz
SET Rank = ?
WHERE Uzaname = ?"""
# BIND WITH TUPLE OF PARAMS IN SECOND ARG
cursor.execute(sql, (NewRank, Findaname))
conn.commit()
If you do connect to a different database, call ATTACH. Here also, you can alias other database with better naming instead of number leading identifier.
cursor.execute("ATTACH '/path/to/0rk_D4T4B453.db' AS other_db")
sql = """UPDATE other_db.Da_Boyz
SET Rank = ?
WHERE Uzaname = ?"""
cursor.execute(sql, (NewRank, Findaname))
conn.commit()
cur.execute("DETACH other_db")

Inserting values in sqlite 3 but appearing as column names

Im using inputs from SQLite3 in python 3.5 to add user information to a data base. However once i obtain the data and insert into the database, rather than inserting the data into the columns it tells me there is no column.
The error I get is as follows:
Exception in Tkinter callback
Traceback (most recent call last):
File
"C:\Users\Luke_2\AppData\Local\Programs\Python\Python35-32\lib\tkinter__init__.py", line 1549, in call
return self.func(*args) File "C:\Users\Luke_2\Desktop\Computing\Coursework\live\current.py", line
303, in details
cur_user.execute("INSERT INTO LogIn(Email,Password) VALUES("+user+","+passw+")") sqlite3.OperationalError: no such column:
a
And the function in my code doing this is as follows:
def details():
user = email_sign.get()
user1 = email1_sign.get()
passw = password_sign.get()
password1 = password1_sign.get()
if user == user1 and passw == password1:
cur_user.execute("INSERT INTO LogIn(Email,Password) VALUES("+user+","+passw+")")
conn_user.commit()
else:
print("please try again")
It is because the request that you actually execute has no quotes around the values, so the names are interpreted as column names but the SQL engine. If you pass a and b respectively you will execute
INSERT INTO LogIn(Email,Password) VALUES(a,b)
when what is required is
INSERT INTO LogIn(Email,Password) VALUES('a','b')
But you should never to that! Building requests that way but hardcoding parameters in the request has been the cause of SQL injection problems for decades.
The correct way is to build a parameterized request:
cur_user.execute("INSERT INTO LogIn(Email,Password) VALUES(?,?)", (user, password))
simpler, smarter and immune to SQL injection...

Syntax Error near "CHANGE" in sqlite3

I am attempting to execute the following (move a column to be the first one)
import sqlite3
db = sqlite3.connect('adatabase.sqlite')
c = db.cursor()
c.execute('ALTER TABLE tab1 CHANGE COLUMN r r def FIRST')
Unfortunately I get this error
Traceback (most recent call last):
File "<input>", line 1, in <module>
OperationalError: near "CHANGE": syntax error
What could be? Thanks in advance
SQLite does not support a CHANGE COLUMN feature; if any.
Only the RENAME TABLE and ADD COLUMN variants of the ALTER TABLE
command are supported
See all missing features: SQL Features That SQLite Does Not Implement

Error in loading database entries into lists

I'm getting the following error:
Traceback (most recent call last):
File "/home/pi/Nike/test_two.py", line 43, in <module>
do_query()
File "/home/pi/Nike/test_two.py", line 33, in do_query
for(Product,Bin,Size,Color) in records:
ValueError: too many values to unpack
Code:
def do_query():
connection = sqlite3.connect('test_db.db')
cursor = connection.cursor()
cursor.execute("SELECT * FROM TESTER ORDER BY CheckNum")
records = cursor.fetchall()
for(Product,Bin,Size,Color) in records:
row_1.append(Product)
row_2.append(Bin)
row_3.append(Size)
row_4.append(Color)
connection.commit()
cursor.close()
connection.close()
do_query()
I'm trying to load each column of a table into seperate python list. I am using Python, and sqlite3. Why am I getting this error?
You are using "SELECT *" which will return every column from the table. My guess is that the table in question contains more columns then the 4 you specified.
A better way would actually be specifying in the SQL which columns you want so that your code will not break if columns are added to the database.
Something like "SELECT col1, col2 FROM table"
You can run the sqlite3 tool on the db file and then view the table schema with ".schema <table_name>"

Python and MySQL STR_TO_DATE

When I execute the code (see below) I got the next error
Traceback (most recent call last):
File "/home/test/python/main.py", line 18, in <module>
calls = tel.getCallRecordings(member['id'], member['start_date'])
File "/home/test/python/teldb.py", line 49, in getCallRecordings
'start_date': str(start_date),
File "/usr/local/lib/python2.5/site-packages/MySQL_python-1.2.3-py2.5-freebsd-8.1-RELEASE-amd64.egg/MySQLdb/cursors.py", line 159, in execute
TypeError: int argument required
The code I use is the next:
def getCallRecordings(self, member_id, start_date):
self.cursor.execute("""
SELECT var10 as filename,
var9 as duration
FROM csv_data c
LEFT JOIN transcriptions t ON
c.id=t.call_id
WHERE member_id=%(member_id)s AND
var10 IS NOT NULL AND
var9>%(min_duration)d AND
dialed_date>STR_TO_DATE(%(start_date)s, '%%Y-%%m-%%d %%H:%%i:%%s') AND
t.call_id IS NULL
ORDER BY dialed_date DESC
""", {
'member_id': member_id,
'min_duration': MIN_DURATION,
'start_date': str(start_date),
})
logging.debug("Executed query: %s" % self.cursor._executed)
return self.cursor.fetchone()
Why I got this error? Thanks.
You don't show what MIN_DURATION is, but you use %(min_duration)d, so it is required to be an int. Do you have it defined as a string or a float instead?
You don't need to use %d in a SQL query like this, the DB adapter understands the types you pass it, and will properly insert them into the query. Make MIN_DURATION an integer (perhaps with int(MIN_DURATION) in the code you have), and it will work.
BTW: the stack trace focuses you on the str(start_date), but only because that's the last source line in the executable statement that had the error, so it's misleading.
I have faced a similar issue while constructing the sql query strings involving str_to_date function. I have used .format() operator on python strings to parametrize the SQL queries. Here is an example query that would work just fine:
# Takes an input date and returns the manager's name during that period
input_string='"' + "{input_data}".format(input_data=input_data) + '"'
sql_query='''select CONCAT(e.last_name, ",", e.first_name),STR_TO_DATE(from_date,'%Y-%m-%d'),STR_TO_DATE(to_date,'%Y-%m-%d') from dept_manager dm inner join employees e on e.emp_no=dm.emp_no where STR_TO_DATE({input_string},'%Y-%m-%d')>STR_TO_DATE(from_date,'%Y-%m-%d') and STR_TO_DATE({input_string},'%Y-%m-%d')<STR_TO_DATE(to_date,'%Y-%m-%d');'''.format(input_string=input_string)

Categories