Uploading image to mariadb database - python

I'm new to sql so maybe this is just a beginner's mistake, but after trying some solutions I found here and there I'm still unable to solve this problem. I'm trying to upload an image to a mariadb database through a python script which looks like this:
import mysql.connector
path=input("File to upload: ")
with open(path,'rb') as f:
fileData=f.read()
query=f"UPDATE emp SET image={fileData} WHERE empId=1;"
db=mysql.connector.connect(...)
myCursor=db.cursor()
myCursor.execute(query)
myCursor.close()
db.close()
print(f"Uploaded {path} to the database...")
However, when the code reaches myCursor.execute(query) I get the following error:
Traceback (most recent call last):
File "webSqlSampleClient.py", line 16, in <module>
myCursor.execute(query)
File "/home/asriel/.local/lib/python3.8/site-packages/mysql/connector/cursor.py", line 551, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "/home/asriel/.local/lib/python3.8/site-packages/mysql/connector/connection.py", line 490, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "/home/asriel/.local/lib/python3.8/site-packages/mysql/connector/connection.py", line 395, in _handle_result
raise errors.get_exception(packet)
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xe1\x00'' at line 1
What's wrong with my code? The rest of the query seems correct as I've used the very same UPDATE statement with other non-image values successfully.
Thank you in advance for the help.
-Update:
As #tadman suggested, I've used %s as a placeholder in my sql query, so the new code looks like this:
query="UPDATE emp SET image=%s WHERE empId=1"
db=mysql.connector.connect(...)
myCursor=db.cursor()
myCursor.execute(query, (fileData,))
myCursor.close()
db.close()
The code above doesn't run into any exceptions and prints the intended output, however, when I execute the following SQL statement in my SQL client:
SELECT image
FROM emp
WHERE empId = 1;
it says that the value for image is NULL.
What's wrong now? image is a blob, in case that's not clear.

Ok, so I've just got it to work:
the answer I used to solve the first problem was #tadman's answer (which is in the question's comments). The problem I had with the database not updating its values was solved by adding db.commit() (I forgot that, silly mistake). Thanks for all of your helpful comments anyways!

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")

SQL statement failing to execute in Python CGI

I have an update statement in my database that is not executing. As far as I am aware, it is syntactically correct. I used this app to verify the syntax. The except block is all that is being executed and I do not understand why.
Here is the code:
for res_posts in list_of_response_ids:
temp_str = res_posts[0] # first element of res_posts tuple is string
temp_str += ":" + str(output[0])
try:
sql = "UPDATE POST SET res_post_id = %s WHERE post_id = %d;" % (str(temp_str), int(res_posts[1]))
cursor.execute(sql)
except:
print "uh oh"
I can post more code if this is not enough information.
EDIT: Following Jacob's advice, I used raise and got the following error:
Traceback (most recent call last):
File "post.cgi", line 93, in <module>
cursor.execute(sql)
File "/usr/lib64/python2.6/site-packages/MySQLdb/cursors.py", line 173, in execute
self.errorhandler(self, exc, value)
File "/usr/lib64/python2.6/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':37 WHERE post_id = 8' at line 1")
Thank you so much!
Based on your traceback, there is something wrong with the type of entry you are using for the res_post_id or post_id. Currently you are not passing a representation of the res_post_id string, but a literal string. If res_post_id is a string in your DB Schema, I would recommend using %r like so:
sql = "UPDATE POST SET res_post_id = %r WHERE post_id = %d;" % (str(temp_str), int(res_posts[1]))
This will properly quote your res_post_id value for insertion.
So your statement should change from this:
UPDATE POST SET res_post_id = :37 WHERE post_id = 8;
...to this:
UPDATE POST SET res_post_id = ':37' WHERE post_id = 8;

Mysql query using python

I'm using python 3.x and mysql.connector to access a Mysql database. I'm having an issuing with querying the database.
When I run the following query, I get the correct result:
cursor.execute("SELECT idx FROM db WHERE name = 'John Smith'")
When I try and run the following query I get an error:
cursor.execute("SELECT idx FROM db WHERE name = %s",'John Smith')
File "<input>", line 1, in <module>
File "C:\Python34\lib\site-packages\mysql\connector\cursor.py", line 515, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "C:\Python34\lib\site-packages\mysql\connector\connection.py", line 488, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "C:\Python34\lib\site-packages\mysql\connector\connection.py", line 395, in _handle_result
raise errors.get_exception(packet)
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s' at line 1
I've tried running the following query instead, but it appears that the query searches for "%s" not the string "John Smith"
cursor.execute("SELECT idx FROM db WHERE name = '%s'",'John Smith')
I'm not sure if the error is due to the fact that I'm using a string with spaces in it or not, but I haven't been able to solve the problem.
q="SELECT idx FROM db WHERE name = %s";
cursor.execute(q,'Xander')
Formatting just needs to be changed a little. You were pretty close.
foo = 'John Smith'
cursor.execute("SELECT idx FROM db WHERE name = %s", (foo,))
Take a gander at the links below for more explanation
Python MySQL Parameterized Queries
https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html
According to the docs, you would need to write:
cursor.execute("SELECT idx FROM db WHERE name = %s", ('John Smith'))
In other words, the parameter-replacement values must be contained in an iterable.
(But see the answer from theClap who correctly adds a semi-colon to force "tupleness" where required).

SQLite error in 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.

Execute a PL/SQL function (or procedure) from SQLAlchemy

I have a legacy PL/SQL function:
getlogin(p_username in varchar2, p_password in varchar2) return boolean;
How can I execute this from SQLAlchemy and get the return value?
A naive approach like this doesn't seem to work:
result = DBSession.execute('getlogin(:username, :password)',
{'username':request.POST['username'],'password':request.POST['password']});
# extract return value from result
From the logs I see this error:
File "../env/lib/python3.3/site-packages/SQLAlchemy-0.8.0-py3.3.egg/sqlalchemy/engine/base.py", line 871, in _execute_context
context)
File "../env/lib/python3.3/site-packages/SQLAlchemy-0.8.0-py3.3.egg/sqlalchemy/engine/default.py", line 322, in do_execute
cursor.execute(statement, parameters)
cx_Oracle.DatabaseError: ORA-00900: invalid SQL statement
I can see it looks like the SQL interpreter is being invoked and not the PL/SQL interpreter, but I'm not sure on the next steps.
You'll probably have to provide a PL/SQL block to your execute call:
result = DBSession.execute('begin getlogin(:username, :password); end;',
{'username':request.POST['username'],'password':request.POST['password']});
This SO question on SQLAlchemy + Oracle SP might also help.
If you're using .execute() on a connection method then you need a valid SQL statement. If getlogin is a function, this requires a SELECT:
result = DBSession.execute('select getlogin(:username, :password) from dual'
, {'username' : request.POST['username']
,'password' : request.POST['password']});
As the error states, your SQL statement is invalid.

Categories