MySQL/Python connector not being able to search [duplicate] - python

This question already has an answer here:
MySQL/Python -> Wrong Syntax for Placeholder in Statements?
(1 answer)
Closed 4 years ago.
import mysql.connector
config = {
'user': 'root',
'password': '*******',
'host': '127.0.0.1',
'database': 'mydb',
'raise_on_warnings': True
}
cnx = mysql.connector.connect(**config)
cursor = cnx.cursor()
find_user = ("SELECT * FROM HM_Login WHERE Username = '%s' ")
data_Pupil = {
'Username': "GJM"
}
cursor.execute(find_user, data_Pupil)
lit = cursor.fetchall()
print(lit)
cursor.close()
cnx.close()
I have a database that works and i am having a problem trying to search the database and pull one row of one column when i was inserting into the database the %S worked just fine but now it only works if i have a value inside the the query. this is using the mysql connector for python.
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 '' at line 1
I am getting this error which is extremely insightful and not helpful at all if there is anything you can do to help it would mean a lot.

As the error statement says. You have an SQL error. You are trying to input a variable as a positional parameter but you've used a dictionary on a variables 'place'.
Instead you should use %s for variables and tuples with variables and then do the following:
find_user = "SELECT * FROM HM_Login WHERE Username = %s"
data_Pupil = ('GJM',)
cursor.execute(find_user, data_Pupil)
It is also possible to use dictionary - but you shouldn't. Despite that I'm still going to show it here as I had to dig into the explanation to understand why.
find_user = "SELECT * FROM HM_Login WHERE Username = '{Username}'".format(**data_Pupil)
data_Pupil = {
'Username': "GJM"
}
The above opens up for sql-injections, as I was told per the comments - and here is why; Say we have a username that is identical to the following:
username = "'MR SQL Injection');DROP TABLE HM_Login;"
That would result in an SQL Query that drops the table.
SELECT * FROM HM_Login WHERE Username = 'MR SQL Injection');DROP TABLE HM_Login;
To avoid sql-injection as above. Use the first solution

Your placeholder syntax is for positional parameters but you've used a dictionary. Replace that with a tuple:
find_user = ("SELECT * FROM HM_Login WHERE Username = %s")
data_pupil = ('GJM',)
cursor.execute(find_user, data_Pupil)

Related

Check row exists in MySQL through function in python class

I am trying to implement a function in my database manager class that checks if a row (user) exists (through their email) in my MySQL table.
See code below:
def has_user(self, table_name : str, user_credentials: UserCredentials) -> bool:
mysql_hasuser_query = """
SELECT COUNT(1) FROM {t_name} WHERE email = {u_email}
""".format(t_name=table_name, u_email=user_credentials.email)
cursor = self.connection.cursor()
cursor.execute(mysql_hasuser_query)
if cursor.fetchone()[0]:
print("User exists in database!")
return True
I am receiving the following syntax error 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 '#gmail.com' at line 1
However, I implemented this in MySQL query editor and it worked fine. I am not sure what I am doing wrong here.
You're not quoting the email in the query. But you should use a parameter instead of formatting the string into the query.
def has_user(self, table_name : str, user_credentials: UserCredentials) -> bool:
mysql_hasuser_query = """
SELECT COUNT(1) FROM {t_name} WHERE email = %s
""".format(t_name=table_name)
cursor = self.connection.cursor()
cursor.execute(mysql_hasuser_query, (user_credentials.email,))
if cursor.fetchone()[0]:
print("User exists in database!")
return True

Tuple decryption problem using cryptography.fernet

ok so I'm trying to code a password manager in python and I'm using cyrptography.fernet to crypt the emails and passwords and then store them into a local SQLite database the problem is that when I try to get for example the emails in the database they are in this format: (b'encypted-email-here'), (b'and-so-on) so I thought since theres the b before the quotes it's in bytes format and I do not need to do anything in order to decrypt them but when I actually try to decrypt them I get an error saying: "TypeError: token must be bytes" here is my code so you can take a look at it
b_email = email.encode('utf-8')
b_pwd = pwd.encode('utf-8')
enc_email = f.encrypt(b_email)
enc_pwd = f.encrypt(b_pwd)
conn = sqlite3.connect('database.db')
execute = conn.cursor()
execute.execute('CREATE TABLE IF NOT EXISTS logins (website, email, password)')
execute.execute('INSERT INTO logins VALUES (:website, :email, :password)', {'website': website, 'email': enc_email, 'password': enc_pwd})
conn.commit()
conn.close()
def view():
con = sqlite3.connect('database.db')
cur = con.cursor()
iterable = cur.execute('SELECT email FROM logins')
for email in iterable:
dec_email = f.decrypt(email)
print(dec_email)```
cur.execute() returns a sequence of rows, each of them is a tuple. In your case, a tuple of just one element, but still you need to extract the email from it. The most elegant way would be unpacking (notice the comma after email):
for email, in cur.execute('SELECT email FROM logins'):
print(f.decrypt(email))

Python SQLite Update Function not working

I'm using Python 3.7.5 and SQLite3 3.X as well as Tkinter (but that's irrelevant) and I can't seem to update my table called "Account"
try:
Cursor.execute("""CREATE TABLE Account (
Application text,
Username text,
Password text)""")
except sqlite3.OperationalError:
Cursor.execute("""UPDATE Account SET
Application = :NewApp,
Username = :NewUser,
Password = :NewPass
WHERE oid = :oid""",
{"NewApp": NewApplicationE.get(),
"NewUser": NewUsernameE.get(),
"NewPass": NewPasswordE.get(),
"oid": X[3]
})
The try bit is just to create the table if there's not already one and if there is it goes on to update the table
I know for a fact there's columns called Application, Username, Password and the variable.get() all returns the proper string
The oid being X[3] gives you an integer
The program runs but it doesn't actually seem to update anything.
Any help with the formatting or just in general would be appreciated
I think that you need just commit your change
I assume that you get cursor from a connectio,
For instance something like that should work:
import sqlite3
conn = sqlite3.connect('example.db')c = conn.cursor()
Cursor = conn.cursor()
try:
Cursor.execute("""CREATE TABLE Account (
Application text,
Username text,
Password text)""")
conn.commit()
except sqlite3.OperationalError:
Cursor.execute("""UPDATE Account SET
Application = :NewApp,
Username = :NewUser,
Password = :NewPass
WHERE oid = :oid""",
{"NewApp": NewApplicationE.get(),
"NewUser": NewUsernameE.get(),
"NewPass": NewPasswordE.get(),
"oid": X[3]
})
conn.commit()
conn.close()
Referece
https://docs.python.org/3/library/sqlite3.html

Save resulting dict from api into db - psycopg2

I want to save an API response, on some table of my database, I'm using Postgres along with psycopg2.
This is my code:
import json
import requests
import psycopg2
def my_func():
response = requests.get("https://path/to/api/")
data = response.json()
while data['next'] is not None:
response = requests.get(data['next'])
data = response.json()
for item in data['results']:
try:
connection = psycopg2.connect(user="user",
password="user",
host="127.0.0.1",
port="5432",
database="mydb")
cursor = connection.cursor()
postgres_insert_query = """ INSERT INTO table_items (NAME VALUES (%s)"""
record_to_insert = print(item['name'])
cursor.execute(postgres_insert_query, record_to_insert)
connection.commit()
count = cursor.rowcount
print (count, "success")
except (Exception, psycopg2.Error) as error :
if(connection):
print("error", error)
finally:
if(connection):
cursor.close()
connection.close()
my_func()
I mean, I just wanted to sort of "print" all the resulting data from my request into the db, is there a way to accomplish this?
I'm a bit confused as You can see, I mean, what could be some "print" equivalent to achieve this?
I mean, I just want to save from the API response, the name field, into the database table. Or actually INSERT that, I guess psycopg2 has some sort of function for this circumstance?
Any example You could provide?
EDIT
Sorry, I forgot, if I run this code it will throw this:
PostgreSQL connection is closed
A particular name
Failed to insert record into table_items table syntax error at or near "VALUES"
LINE 1: INSERT INTO table_items (NAME VALUES (%s)
There are a few issues here. I'm not sure what the API is or what it is returning, but I will make some assumptions and suggestions based on those.
There is a syntax error in your query, it is missing a ) it should be:
postgres_insert_query = 'INSERT INTO table_items (NAME) VALUES (%s)'
(I'm also assuming thatNAME` is a real column in your database).
Even with this correction, you will have a problem since:
record_to_insert = print(item['name']) will set record_to_insert to None. The return value of the print function is always None. The line should instead be:
record_to_insert = item['name']
(assuming the key name in the dict item is actually the field you're looking for)
I believe calls to execute must pass replacements as a tuple so the line: cursor.execute(postgres_insert_query, record_to_insert) should be:
cursor.execute(postgres_insert_query, (record_to_insert,))

Python connector error on trying to delete using user input

I have implemented most other basic database transactions including insert,update,select with similar syntax,but on trying to delete,i get error
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
What would the correct syntax be? I must delete according to user input. Here is a shortened version of my code,minus the insert,select,update part.:
elif (choice == 4):
mail=raw_input('Enter email of user to be deleted:')
print 'Deleting..'
delete_user_details(mail)
def delete_user_details(email):
sql = "DELETE FROM users WHERE email = %s"
cursor.execute(sql,email)
You need to pass query parameters to cursor.execute() as a tuple, even for a single parameter. Try this:
sql = "DELETE FROM users WHERE email = %s"
cursor.execute(sql, (email,))

Categories

Resources