String replacement in SQL Query using Python - python

I have two queries in SQL which are the following:
q1 = select date_hour from table
And, the second query is:
q2 = select date(date_hour) from table
The only difference between these queries is the string date_hour and date(date_hour). SO, I tried parameterising my query in the following manner:
q1 = select %s from table
cur.execute(q1,'date')
cur.execute(q1,'date(date_hour)')
However, this throws an error which is:
not all arguments converted during string formatting
Why am I getting this error? How can I fix it?

Change the comma in cur.execute to %
Change this:
q1 = "select %s from table"
cur.execute(q1,'date')
cur.execute(q1,'date(date_hour)')
to:
q1 = "select %s from table"
cur.execute(q1 % 'date')
cur.execute(q1 % 'date(date_hour)')

It's unclear wich sql library you're using but assuming it uses the Python DB API:
Sql parameters are typically used for values, not columns names (while this is possible using stored procedures).
It seems you're confused between string formatting in python and sql parametized queries.
While %s can be used to format a string (see formatting strings) this is not the way to set sql parameters.
See this response to use sql parameters in python.
By the way i can't see anything wrong with this simple code:
cursor=cnx.curor()
query="select date_hour from table"
cursor.execute(query)
query="select date(date_hour) from table"
cursor.execute(query)

Change your code to something like this:
q1 = "select %s from table"
cur.execute(q1,['date'])
cur.execute(q1,['date(date_hour)'])
Check this

Related

Can I use an input to add things to a POSTGRES TABLE? (Python)

I'm trying to transfer a user input from a python code to a table in postgresql
What I want to do is place an input() in this code and make it's value go to the comment (#) in the code.
conn = psycopg2.connect(
host="localhost",
database="Twitterzuil",
user="postgres",
password="")
cur = conn.cursor()
cur.execute("INSERT INTO Bericht2 (name) VALUES (#THIS IS WHERE I WANT THE INPUT TO GO)");
conn.commit()
I have no idea how, I'm really a beginner in all this so any help is appreciated
I believe what you are asking about is called string interpolation. Using f-style format, this might look like
new_name = "'bob'" # need single quotes for SQL strings
sql = f"INSERT INTO Bericht2 (name) VALUES ({new_name})" # => sql == "INSERT INTO Bericht2 (name) VALUES ('bob')"
cur.execute(sql)
Note the f at the start of the string, when you do this expressions inside {} pairs get replaced with their python values (tutorial). There are also string formatting approaches involving % substitution and the .format method on strings.
If you are doing anything beyond the basics you should look into using the SQLAlchemy package; here's the link to their insert api. Using SQLAlchemy will help reduce the risks that can come with manually constructing SQL queries.
Example from "Inserting Rows with SQLAlchemy"
from sqlalchemy import insert
stmt = insert(user_table).values(name='spongebob', fullname="Spongebob Squarepants")
with engine.connect() as conn:
result = conn.execute(stmt)
conn.commit()

Passing parameters to LIKE SQL query

I want to pass dynamic parameter to the LIKE query using Fast API (Python) coming from the query parameter. I have tried a lot of ways but I don't know what I am doing wrong.
The query I need to use is :
SELECT Time, table_id, Text FROM tablename WHERE Text LIKE '%text%'
The python code for getting query parameter is :
def get_result(text : str):
con = connection.connect()
statement = 'SELECT Time, table_id, Text FROM tablename WHERE Text LIKE '%text%''
How will I pass the dynamic text parameter in this query because this gives the error saying "TypeError: not all arguments converted during string formatting"?
You cannot nest single quotes. Also, it's clearer to use a f-string for string formatting here. Try:
statement = f"SELECT Time, table_id, Text FROM tablename WHERE Text LIKE '%{text}%'"
NEVER substitute values directly in to a SQL string like that. EVER. Use parameterised queries / bind variables.
For example, depending on the driver/library you're using, you may be able to use...
con = connection.connect()
cur = con.cursor()
cur.execute("SELECT Time, table_id, Text FROM tablename WHERE Text LIKE %s", ('%' + text + '%',))

Error fromatting parameter for Pandas read_sql_query

How do I fix this error on passing a string parameter into pd.read_sql_query? Using Python 2.7.
table = 'mytable1'
query = (
"SELECT * "
"FROM ? "
)
df = pd.read_sql_query(sql=query, con=conn, params=(table))
pandas.io.sql.DatabaseError: Execution failed on sql 'SELECT * FROM ? ': near "?": syntax error
I have tried replacing ? with % and %s but it returns the same error.
The following equality example works as expected:
query = (
"SELECT * "
"FROM mytable1 "
"WHERE name = ? "
)
df = pd.read_sql_query(sql=query, con=conn, params=('cat',))
Note that the comma in params appears to be required, otherwise this error is returned: Incorrect number of bindings supplied. The current statement uses 1, and there are 7 supplied.
I have also tried params=(table,) in my problem but no luck. I know that alternatively I can do this with "FROM '{t}' ").format(t=table), but I would like to understand how to use Pandas' built-in parameters option.
The problem is that params is intended to replace values, not SQL keywords (FROM, SELECT, etc...) or tables or columns.
You can't specify table that way, you have to use a string substitution.
query = (
f"SELECT * "
"FROM {table} "
)
However, be very, very, very careful. Doing this, rather than using params opens you up to a very big family of vulnerabilities, SQL Injections.
Don't do it if you get the table names from external sources.
(Oh, and the likely reason for this limitation is that, besides their absolute necessity for security reasons, parametrized queries allow the database engine to examine the query, look at indices, statistics and all that and draw up an "execution plan". Successive calls then can reuse that execution plan and just substitute in the new variables. That could not be done if the query was changing in terms of what tables and columns were being accessed.)

Not enough arguments for format string error when inserting list into database SQL Python

I'm trying to insert a list into separate columns of a database
print inserter
params = ['%s' for item in inserter]
sql_query = 'INSERT INTO tablename (coloumn1, coloumn2, coloumn3, coloumn4, coloumn5, coloumn6, coloumn7) VALUES (%s,%s,%s,%s,%s,%s,%s);' % ','.join(params)
cursor.execute(sql_query)
db.commit
But keep getting the error
not enough arguments for format string
Anyone know what I am doing wrong?
Anyone know what I am doing wrong?
You are using string interpolation in a query.
This is bad, mainly for 2 reasons:
It is erroneous as you see. The python interpreter is confused between the %s for the interpolation and the %s for the sql parameters.
It makes your code vulnerable for sql injection.
You should use a parametrized query:
sql_query = '''INSERT INTO tablename (coloumn1, coloumn2, coloumn3,
coloumn4, coloumn5, coloumn6, coloumn7)
VALUES (%s,%s,%s,%s,%s,%s,%s);'''
cursor.execute(sql_query, inserter) # assuming inserter is a tuple/list of values

python cursor FROM %s

I try to execute this request :
cur.execute("SELECT MAX(id) FROM %s WHERE equipement_id = %s", (table,eq_id))
But i have error because the FROM %s is not build correctly.
Try like this
cur.execute("""SELECT MAX(id) FROM %s WHERE equipement_id = %s""" % (table, eq_id))
Unfortunately, you need to do it in 2 steps:
table_name = 'stuff'
query = "SELECT MAX(id) FROM {0} WHERE equipement_id = %s".format(table_name)
cur.execute(query, eq_id)
Why? - Database connectors tend to only allow you to substitute values into the query, not arbitrary pieces like table names or expressions. For example, from psycopg2 docs:
Only variable values should be bound via this method: it shouldn’t be used to set table or field names. For these elements, ordinary string formatting should be used before running execute().
And obviously:
triple-check if the value of table_name isn't user controlled and is really a valid table name!
Please read the problem with the query parameters section in psycopg2 docs (even if you end up using another database; the remarks there are quite general).

Categories