i have a question regarding variable injection into sql query with sqlalchemy/python(3.8).
What i researched so far was adding %s and also email_address=? and then adding it (email_address) but without success
What i am trying to do is capture user input and run a select query dynamically.
print(" What is the email address??")
email_address = input()
conn = create_engine("mssql+pyodbc://test_table:username#127.0.0.1:3306/test_db?driver=SQL Server?Trusted_Connection=yes'", echo = False)
sql = pd.read_sql('Select id,email_address from test_table where email_address = email_address', conn)
print(sql)
try:
print(" What is the email address??")
email_address = input()
conn = create_engine("mssql+pyodbc://test_table:username#127.0.0.1:3306/test_db?driver=SQL Server?Trusted_Connection=yes'", echo = False)
sql = pd.read_sql('Select id,email_address from test_table where email_addres=?', conn, params=(email_addres,))
print(sql)
Related
I am trying to run a SQL "SELECT" query in Postgres from Python using Psycopg2. I am trying to compose the query string as below, but getting error message, using psycopg2 version 2.9.
from psycopg2 import sql
tablename = "mytab"
schema = "public"
query = sql.SQL("SELECT table_name from information_schema.tables where table_name = {tablename} and table_schema = {schema};")
query = query.format(tablename=sql.Identifier(tablename), schema=sql.Identifier(schema))
cursor.execute(query)
result = cursor.fetchone()[0]
Error:
psycopg2.error.InFailedSqlTransaction: current transaction is aborted, commands ignored until end of transaction block
Can someone please help. Thanks.
In the (a bit strange) query
select table_name
from information_schema.tables
where table_name = 'mytab'
and table_schema = 'public';
'mytab' and 'public' are literals, not identifiers. For comparison, mytab is an identifier here:
select *
from mytab;
Thus your format statement should look like this:
query = query.format(tablename=sql.Literal(tablename), schema=sql.Literal(schema))
Note that the quoted error message is somewhat misleading as it is about executing a query other than what is shown in the question.
Since this query is only dealing with dynamic values it can be simplified to:
import psycopg2
con = psycopg2.connect(<params>)
cursor = con.cursor()
tablename = "mytab"
schema = "public"
# Regular placeholders
query = """SELECT
table_name
from
information_schema.tables
where
table_name = %s and table_schema = %s"""
cursor.execute(query, [tablename, schema])
result = cursor.fetchone()[0]
# Named placeholders
query = """SELECT
table_name
from
information_schema.tables
where
table_name = %(table)s and table_schema = %(schema)s"""
cursor.execute(query, {"table": tablename, "schema": schema})
result = cursor.fetchone()[0]
I am trying to update a SQL Table given a users input I have the following code. The user can choose to enter in/change the below fields which are defaulted to the values in the SQL table. However when I run the code I get the following error message
mysql.connector.errors.ProgrammingError: Not enough parameters for the SQL statement
I have counted it many times and it seems like the %s match the passed parameters. Am I missing something?
user = User_name_body.get('1.0',END)
passw = Password_text.get('1.0',END)
first = First_name.get('1.0',END)
last = Last_name.get('1.0',END)
phone = Phone_number.get('1.0',END)
email = Email_address.get('1.0',END)
mycursor = mydb.cursor()
sql = "UPDATE t_users SET Email_address=%s, First_name=%s, Last_name=%s, Phone_Number=%s, Password=%s WHERE User_Name=%s VALUES(%s,%s,%s,%s,%s,%s)"
val = (email, first, last, phone, passw,user)
mycursor.execute(sql, val)
mydb.commit()
mydb.close()
UPDATE does not take VALUES, you should change your sql query line to look like this:
sql = "UPDATE t_users SET Email_address=%s, First_name=%s, Last_name=%s, Phone_Number=%s, Password=%s WHERE User_Name=%s"
Python throws an error because you are asking for 12 parameters and only providing 6.
Prepare your sql data like this:
sql = """ UPDATE t_users SET Email_address=%s, First_name=%s, Last_name=%s, Phone_Number=%s, Password=%s WHERE User_Name = %s """
val = (email, first, last, phone, passw, user)
mycursor.execute(sql, val)
or you can do it like this
sql = "UPDATE btms_users SET btms_users.user='%s', btms_users.secret='%s' , btms_users.first_name='%s', " \
"btms_users.second_name='%s', btms_users.email='%s', btms_users.mobile='%s' " \
"WHERE btms_users.id='%s'" % (user_name, user_secret, user_firstname, user_lastname,
user_email, user_phone, user_id)
mycursor.execute(sql)
and here is a full working example:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="test",
database="test"
)
mycursor = mydb.cursor()
sql = "UPDATE items SET name = %s WHERE id = %s"
val = ("Test", 1)
mycursor.execute(sql, val)
mydb.commit()
print(mycursor.rowcount, "record(s) affected")
my_connect = mysql.connector.connect(
host="localhost",
user="xyz",
passwd="xyz",
database="tracking"
)
my_conn = my_connect.cursor()
x = input("enter name")
query="SELECT * FROM trackingtable WHERE Customer_Name = \"x\"";
print(query)
my_conn.execute(query)
my_conn.close()
Query printed statement
How do i get the proper query using the input from user? I tried using placeholders but I couldn't get them to work
Try:
query = f"SELECT * FROM trackingtable WHERE Customer_Name = {x}"
It's an f-string in which you can plug in variables via {}.
If you need the "s inside the query:
query = f'SELECT * FROM trackingtable WHERE Customer_Name = "{x}"'
Do you need the ; at the end?
I am trying to connect to mysql database to retrieve some id for some users and use those id to retrieve another set of data from another table. It should be easy but I am getting mysql errors. Here's a snippet of what I am trying to do.
import MySQLdb
from langdetect import detect
my_db = MySQLdb.connect(
host="localhost",
port = 3306,
user="user",
passwd="password",
db="mydb",
charset = 'utf8'
)
sql1 = """SELECT id, comment FROM users WHERE usertype = 5 LIMIT 100"""
users = []
db_cursor = my_db.cursor()
db_cursor.execute(sql1)
users = db_cursor.fetchall()
sql2 = """SELECT first_name, last_name, email FROM user_contact WHERE id = %s"""
user_contact =[]
for user in users:
comment = user[1]
if detect(comment) == 'en':
id = user[0]
db_cursor = my_db.cursor()
db_cursor.execute(sql2, (id))
temp = db_cursor.fetchall()
user_contact . append (temp)
print (user_contact)
This is the error message I get when I try to run this query.
_mysql_exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query')
The first part of the query will normally go through but it usually fails when it tries to connect to mysql again for the second part. I tested with just 100 records just to check if it's an issue with the query running too long but it's still the same even with 10 records.
For your second part, you might not execute sql;)
Try to change
for user in users:
comment = user[1]
if detect(comment) == 'en':
id = user[0]
db_cursor = my_db.cursor()
temp = db_cursor.fetchall()
user_contact . append (temp)
to
for user in users:
comment = user[1]
if detect(comment) == 'en':
id = user[0]
db_cursor = my_db.cursor()
db_cursor.execute(sql1, (id))
temp = db_cursor.fetchall()
user_contact . append (temp)
I created a db table from terminal, and now i want to insert data to it using following code,sql_insert_reg statement which is used as sql insert command is same as that i use in terminal insert operations but using in python file does not insert data .I am learning use of mysql in flask,here's my code.This code does not give error but does nothing as i expect it to!
mysql = MySQL()
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = 'root'
app.config['MYSQL_DATABASE_DB'] = 'EmpData'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
class RegistrationForm(Form):
username = TextField('Username', [validators.Length(min=4, max=25)])
password = PasswordField('New Password', [
validators.Required(),
validators.EqualTo('confirm', message='Passwords must match')])
confirm = PasswordField('Repeat Password')
accept_tos = BooleanField('I accept the TOS', [validators.Required()])
#app.route('/register',methods=['GET','POST'])
def register():
form = RegistrationForm(request.form)
flash('login details')
session['tmp'] = 43
if request.method == 'POST' and form.validate():
username = form.username.data
password = form.password.data
sql_insert_reg = "INSERT INTO User(userName,password) VALUES(%s,%s)"
#flash(sql_insert_reg)
conn = mysql.connect()
cursor = mysql.get_db().cursor()
cursor.execute(sql_insert_reg,(username,password))
conn.commit()
return render_template('register.html',form=form)
this is the screenshot i uploaded below..please see the entries useId 2 then goes directly to 6 ..and i got to see this by altering the answer as suggested to me!!can anyone lookout the problem behind the scene!
Please help me!
This is what a typical INSERT statement looks like:
INSERT INTO table (column1,column2,column3) VALUES (value1,value2,value3);
Note that if your first column is auto-incremental (e.g. some sort of index), you can ommit that from the statement and just write it as follows:
INSERT INTO User (user_column, pass_column) VALUES ('foo', 'bar');
So... don't do this:
sql = "INSERT INTO Table VALUES(NULL,'%s','%s')"%(username,password)+";"
Do this instead:
sql = "INSERT INTO Table (col1, col2) VALUES (%s, %s)"
cursor.execute(sql, (value1, value2))
Why? Because that will sanitize your input and you don't end up registering Bobby Drop Table as a user.
If doing it that way doesn't do what you expect, please provide more detail on what is happening, what you're expecting and how you know that you don't have what you expect to see.
this could be your problem
ursor.execute(sql_insert_reg,(username,password))
looks like it should be
cursor.execute(sql_insert_reg,(username,password))
and if thats not it, i would just use sqlalchemy to generate the sql for you
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker,scoped_session
import sqlalchemy as sa
Model = declarative_base()
engine = sa.create_engine('mysql://DB_USERNAME:DB_PASSWORD#DB_HOST:DB_PORT/DB_NAME')
Session = scoped_session(sessionmaker(bind=engine))
db_session = Session()
class User(Model):
__tablename__ = 'users'
id = sq.Column(sq.Integer,primary_key=True)
username = sq.Column(sq.String(255),nullable=False,unique=True)
password = sq.Column(sq.Text,nullable=False)
then if you want to manipulate the data you can change this from above
username = form.username.data
password = form.password.data
sql_insert_reg = "INSERT INTO User(userName,password) VALUES(%s,%s)"
#flash(sql_insert_reg)
conn = mysql.connect()
cursor = mysql.get_db().cursor()
ursor.execute(sql_insert_reg,(username,password))
conn.commit()
to this
user = User(username=form.username.data,password=form.password.data)
db_session.add(user)
db_session.commit()
I changed some code and found that instead of using the above lines of code in mysql i got this magic!
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
# disconnect from server
db.close()