"unsupported format character at index " - python

I'm trying to format a PostgreSQL query in python and that query has to have '%' between the name of a survey so I can filter surveys by name.
Here is the code:
sql = """select survey_data
from survey_data.survey_data
where codigo_do_projeto like '%s%'
ORDER BY data_de_inicio_da_coleta desc
limit %s
offset %s"""
However it throws this error:
"unsupported format character 'P' (0x50) at index 79"
I don't know how to make python ignore the "%" character.

You have to escape the %.
sql = """select survey_data
from survey_data.survey_data
where codigo_do_projeto like '%%'||%s||'%%'
ORDER BY data_de_inicio_da_coleta desc
limit %s
offset %s"""
Or you can do:
search_val = '%search_term%'
sql = """select survey_data
from survey_data.survey_data
where codigo_do_projeto like %s
ORDER BY data_de_inicio_da_coleta desc
limit %s
offset %s"""
cur.execute(sql, [search_val, val2, val3])

You need to put the survey_name part inside single quotes:
sql = """SELECT survey_data
FROM survey_data.survey_data
WHERE project_code like '%{0}%'
ORDER BY starting_date desc
LIMIT {1}
OFFSET {2}*{1}""".format(survey_name,items_per_page,page_number)

Related

How to escape the % and \ signs in pymysql using LIKE clause?

I want to find something like "probability: 10%" or "10% high" in my 'events' column, but when I used the code below:
conn = pymysql.connect(host="localhost", port=3306, user='myid', passwd='mypwd', db='mydb', charset='utf8')
curs = conn.cursor()
key = "%"
curs.execute(
"SELECT count(*) AS number FROM city WHERE events LIKE %s",
("%" + key + "%",)
)
it returned every row in the table. It executed this query:
SELECT count(*) AS number FROM city WHERE events LIKE '%%%'
like this, which I didn't intend.
Searching for the backslash sign also gave me incorrect results.
What should I do to get the correct result?
Thanks in advance.
instead of the concat the wildchar in param you could use concat in SQL and pass the value
curs.execute(
"SELECT count(*) AS number FROM city WHERE events LIKE CONCAT('%', %s, '%')",
(key ,)
)
or as uggested by #Notinlist
curs.execute(
"SELECT count(*) AS number FROM city WHERE events LIKE CONCAT('%%', %s, '%%')",
(key ,)
)
You ought to use SQL ESCAPE clause:
curs.execute(
"SELECT count(*) AS number FROM city WHERE events LIKE '%#%%' ESCAPE '#'"
)

The result was empty after raw SQL queries in django but right with same sql in mysql db?

I'm using Django to run raw query, but I just got empty result all time as I can use the generated sql by django in mysql db to get the right result .
raw query as:
SmbFbCampaignStatDaily.objects.raw
(
"""SELECT
async.id AS id,
...
async.name AS NAME,
async.status AS STATUS,
...
async.rule_created AS rule_created,
FROM `smb_fb_campaign_async` async
LEFT JOIN
(SELECT
fb_campaign_id,
SUM(impressions) AS impressions,
SUM(clicks) AS clicks
...
FROM `smb_fb_campaign_stat_daily` WHERE dt BETWEEN %s AND %s
GROUP BY fb_campaign_id) statistic
ON statistic.fb_campaign_id = async.fb_campaign_id
WHERE async.fb_account_id = %s
AND (async.fb_campaign_id LIKE '%%%s%%' OR async.name LIKE "%%%s%%")
ORDER BY %s %s""", (start_date, stop_date, account_id, search_field, search_field, order_field, order)
)
And the generated sql like below :
# exe_ret = SmbFbCampaignStatDaily.objects.raw('''sql'')
# print(exe_ret)
sql:
SELECT
async.id AS id,
...
async.name AS NAME,
async.status AS STATUS,
async.daily_budget AS daily_budget,
statistic.spend AS spend,
statistic.clicks AS clicks,
statistic.impressions AS impressions,
statistic.spend AS spend,
...
FROM `smb_fb_campaign_async` async
LEFT JOIN
(SELECT
fb_campaign_id,
SUM(impressions) AS impressions,
SUM(clicks) AS clicks,
...
FROM `smb_fb_campaign_stat_daily` WHERE dt BETWEEN "2019-04-29" AND "2019-04-29" GROUP BY fb_campaign_id) statistic
ON statistic.fb_campaign_id = async.fb_campaign_id
WHERE async.fb_account_id = "113743809520028"
AND (async.fb_campaign_id LIKE '%%' OR async.name LIKE "%%")
ORDER BY id asc
I can got the right result by using the genrated sql in mysql db, but the same time my rawQueryset was always empty.
print(len(exe_ret ))
# 0
How can I make it work correctly?
Any commentary is very welcome. Great thanks.
You can't use parameter substitution inside an existing string like that. You will need to preprocess your variables. For example:
like_search_field = '%{}%'.format(search_field)
SmbFbCampaignStatDaily.objects.raw
("""...
AND (async.fb_campaign_id LIKE %s OR async.name LIKE %s)
ORDER BY %s %s""", (start_date, stop_date, account_id, like_search_field, like_search_field, order_field, order)
)
to print the raw query use this:
Let say I have Product model
q=Product.objects.raw("select.....")
print(q.query)

Use Python variable in a MySQL Subquery

team = input("Enter the team name: ")
cursor = db.cursor()
sql = "SELECT * FROM `flash_data_archive` WHERE `event_id` IN (SELECT `alternate_id` from `event_list` where `category` = %s)" % team
cursor.execute(sql)
What is the correct notation to have the the string the user entered for 'team' to be used for the category field in the sql subsuery?
Remove the % team from the string. Instead, it should be an argument to .execute.
cursor.execute(sql, team)
This will properly escape it.

How do I avoid inserting duplicate data in PostgreSQL?

How to avoid inserting duplicate data? I only want to insert data that does not already exist. I have written following queries but its not working properly. I'm using PostgreSQL.
title_exits = cursor.execute ("SELECT title,pageid FROM movie_movie WHERE title = %s AND pageid = %s;",(title,pageid))
if title_exits == 0:
cursor.execute("INSERT INTO movie_movie (title,pageid,slug,language) values (%s,%s,%s,%s);",(title,pageid,slug,id))
db.commit()
Update: I tried result = cursor.fetchone ("SELECT count(*) FROM movie_movie WHERE title = %s AND pageid = %s;",(title,pageid)). But I'm getting error message. TypeError: fetchone() takes not arugments (2 given).
Answer related to your update:
You should use "%" symbol instead comma:
result = cursor.fetchone ("SELECT count(*) FROM movie_movie WHERE title = %s AND pageid = %s;" % (title,pageid))
update
as #no_freedom said in comments, think better approach would be
result = cursor.fetchone ("SELECT count(*) FROM movie_movie WHERE title = :1 AND pageid = :2", [title,pageid])
But i'm not sure, just try it.
Try to define title field as unique(must define as varchar(constant_length)). Then try insert title into database if title exists, db return error else will insert
As I suspected (and #tony points out) cursor.execute does not return the number of rows. It always return None.

How can I format strings to query with mysqldb in Python?

How do I do this correctly:
I want to do a query like this:
query = """SELECT * FROM sometable
order by %s %s
limit %s, %s;"""
conn = app_globals.pool.connection()
cur = conn.cursor()
cur.execute(query, (sortname, sortorder, limit1, limit2) )
results = cur.fetchall()
All works fine but the order by %s %s is not putting the strings in correctly. It is putting the two substitutions in with quotes around them.
So it ends up like:
ORDER BY 'somecol' 'DESC'
Which is wrong should be:
ORDER BY somecol DESC
Any help greatly appreciated!
paramstyle
Parameter placeholders can only be used to insert column values. They can not be used for other parts of SQL, such as table names, statements, etc.
%s placeholders inside query string are reserved for parameters. %s in 'order by %s %s' are not parameters. You should make query string in 2 steps:
query = """SELECT * FROM sometable order by %s %s limit %%s, %%s;"""
query = query % ('somecol', 'DESC')
conn = app_globals.pool.connection()
cur = conn.cursor()
cur.execute(query, (limit1, limit2) )
results = cur.fetchall()
DO NOT FORGET to filter first substitution to prevent SQL-injection possibilities
Not all parts of an SQL query can be parametrized. The DESC keyword for example is not
a parameter. Try
query = """SELECT * FROM sometable
order by %s """ + sortorder + """
limit %s, %s"""
cur.execute(query, (sortname, limit1, limit2) )
You could try this alternatively...
query = """SELECT * FROM sometable
order by {0} {1}
limit {2}, {3};"""
sortname = 'somecol'
sortorder = 'DESC'
limit1 = 'limit1'
limit2 = 'limit2'
print(query.format(sortname, sortorder, limit1, limit2))

Categories

Resources