How to perform a parametrized raw query in Django? - mysql

I'm reading the official Django documentation, but I can't find an answer to my question.
Right now I have this query implemented, working with a custom MariaDB connector for Django:
results = []
cursor = get_cursor()
try:
sql="SELECT a.*, COALESCE( NULLIF(a.aa, '.'), NULLIF(a.gen, '.') ) AS variant, b.*, c.* FROM `db-dummy`.sp_gen_data c JOIN `db-dummy`.gen_info a ON a.record_id = c.gen_id JOIN `db-dummy`.sp_data b ON b.record_id = c.sp_id WHERE a.gene_name LIKE concat(?, '%') AND a.report_notation LIKE concat('%', ?, '%') AND b.sp_id LIKE concat(?, '%');"
data = (gen, var, sp)
cursor.execute(sql, data)
except mariadb.Error as e:
print(f"Error: {e}")
columns = [column[0] for column in cursor.description]
results = []
for row in cursor.fetchall():
results.append(dict(zip(columns, row)))
return results
It works, but now I need to adapt this query to the django's default MySQL backend.
What I've tried:
results = []
cursor = get_cursor()
sql="SELECT a.*, COALESCE( NULLIF(a.aa, '.'), NULLIF(a.gen, '.') ) AS variant, b.*, c.* FROM `db-dummy`.sp_gen_data c JOIN `db-dummy`.gen_info a ON a.record_id = c.gen_id JOIN `db-dummy`.sp_data b ON b.record_id = c.sp_id WHERE a.gene_name LIKE %s AND a.report_notation LIKE %s AND b.sp_id LIKE %s;"
data = ('{}%'.format(gen), '{}%'.format(var), '{}%'.format(sp))
cursor.execute(sql, data)
columns = [column[0] for column in cursor.description]
results = []
for row in cursor.fetchall():
results.append(dict(zip(columns, row)))
return results
So basically what I had to change to make it work was LIKE concat(?, '%') for LIKE %s.
The problem is, for the a.report_notation LIKE concat('%', ?, '%') part, I do not know how to convert it to something that Django can interpret.
Any ideas?

Your first query should be fine just adjusted to match the format that Django expects.
First, replace ? with %s to pass parameters to the query
Second, replace % with %% as a single percent is an "escape" character and you need to escape the escape char
DOCS
Here's your original query truncated to show an example of how it could work
sql="... WHERE a.gene_name LIKE concat(%s, '%%') AND a.report_notation LIKE concat('%%', %s, '%%') AND b.sp_id LIKE concat(%s, '%%');"
data = (gen, var, sp)
cursor.execute(sql, data)

Related

Replace substring from an table with an stringified value of another table

So I have 2 tables and one contains an string with an ID I want to replace with an string by another table.
I came up with this SQL, which should work, but it seems like an LEFT JOIN isn't allowed in this case.
UPDATE sales_channel_api_context AS api
SET api.payload = REPLACE(
api.payload,
SUBSTRING(
api.payload,
LOCATE('paymentMethodId":"', api.payload)+18,
32
),
LOWER(HEX(c.default_payment_method_id))
)
LEFT JOIN customer AS c
ON c.id = api.customer_id
WHERE api.payload LIKE '%paymentMethodId%' AND api.customer_id IS NOT NULL;
Does anyone know an SQL Query that does exactly this, without creating another table?
An temp table can be used but an new permanent table is no solution.
ChatGPT gave me a working solution and it is as follow:
UPDATE sales_channel_api_context
JOIN customer c ON c.id = sales_channel_api_context.customer_id
SET payload =
CASE
WHEN payload LIKE '%paymentMethodId%' THEN
REPLACE(
payload,
SUBSTRING(
payload,
LOCATE('paymentMethodId":"', payload) + 18,
32
),
LOWER(HEX(c.default_payment_method_id))
)
ELSE payload
END
WHERE sales_channel_api_context.customer_id IS NOT NULL;

how to use Like operator here in mysql for searching user name by his/her character?

SELECT GP.Param_ID, GP.Value, GP.Value_Hindi, GP.Param_Type_ID, GPTM.Param_Type_Name, GPTM.Param_Type_Name_Hindi, GP.Is_Active
FROM M_Global_Param GP
INNER JOIN M_Global_Param_Type_Master GPTM ON GP.Param_Type_ID = GPTM.Param_Type_ID
WHERE GP.Param_ID = IFNULL(NULL,GP.Param_ID)
AND GP.Param_Type_ID = IFNULL(NULL,GP.Param_Type_ID)
AND GPTM.Param_Type_Name = IFNULL(NULL,GPTM.Param_Type_Name)
AND (GP.value IFNULL OR VALUE LIKE '%' + value+ '%')
AND GP.Is_Active = IFNULL('1',GP.Is_Active)
ORDER BY GPTM.param_Type_Name;
how to use 'like' operator in mysql for searching by user name of character.
AND (GP.value IFNULL OR VALUE LIKE '%' + value+ '%')
getting SQL syntax error this line

MySql Remove All Substrings that Match Table Values

I have a VARCHAR variable and I would like to remove all substrings that match a column in a table. So far I have built a query that will return all rows that are a substring of my variable, using the following query:
SET #myval = '%For Her, Shoes,, Sizes 14-24%';
SELECT strReplace
FROM tbl_StringsToReplace
WHERE #myval LIKE CONCAT('%', strReplace, '%');
But I am having trouble writing a REPLACE query that will replace multiple values. I am trying to write something like the following:
SET #myval = REPLACE((SELECT strReplace
FROM tbl_StringsToReplace
WHERE #myval LIKE CONCAT('%', strReplace, '%')), '', #myval);
But I am getting the error:
Error Code: 1242. Subquery returns more than 1 row
I would love to achieve this in pure SQL. Euther way, any advice would be greatly appreciated. Thanks
Try:
SET #myval = '%For Her, Shoes,, Sizes 14-24%';
select val into #myval
from (
SELECT #myval := replace(#myval, strReplace, '') val
FROM tbl_StringsToReplace
) r
order by length(val)
limit 1;
select #myval;

Select query in mysql using COALESCE

I want to write a select statement that should filter data based on wildcard characters. I have written something like this but it doesn't serve my purpose:
Select r.CompanyID,r.Description,c.BusinessUnitID,c.BusinessSourceID as BusinessSrcID,
c.Description as BusinessDesc from RCompanyTable r
join CBusinessUnitTable c on r.CompanyID=c.CompanyID
WHERE r.CompanyID like CASE WHEN COALESCE('Regexp(*)', '') = '' THEN r.CompanyID ELSE 'Company2' END
But in this it always executes the else part.
What i am looking for is it should give me all data when i pass * to the condition.
Since in my RCompanyTable i have two records Company1 and Company2, I want that if i pass * in that query then it should return me both company1 and company2 data but if i pass regexp(any1) it should provide me Comapany1 Data and if both conditions are not true then it should go to else part displaying Company2 data
Looking forward to your answer.
Thanks in advance
I don't know exactly what you want with * and regexp(any1), but assuming that they are constant strings, then this query should work:
SET #parameter = '';
Select r.CompanyID
, r.Description
, c.BusinessUnitID
, c.BusinessSourceID AS BusinessSrcID
, c.Description AS BusinessDesc
FROM RCompanyTable r
JOIN CBusinessUnitTable c ON r.CompanyID = c.CompanyID
WHERE (#parameter LIKE '%*%' AND r.CompanyID IN ('Company1', 'Company2'))
OR (#parameter LIKE 'regexp(any1)' AND r.CompanyID = 'Company1')
OR (#parameter NOT IN ('%*%', 'regexp(any1)') AND r.CompanyID = 'Company2')
The #parameter is what you are going to pass in the query.
WHERE r.CompanyID = CASE WHEN r.CompanyId LIKE '%*%' THEN r.CompanyID ELSE 'Company2' END
This where clause returns all records where companyID has a * in it, or the companyID is Company2. Is this what you are after?

For loop in python and use elements of list as variables for MYSQL query

two questions:
So I have a list of filenames, each of which I would like to feed into a MYSQL query.
The first questions is how to loop through the filelist and pass the elements (the filenames) as a variable to MYSQL?
The second question is: How do I print the results in a more elegant way without the parenthesis and L's form the Tuple output that is returned? THe way I have below works for three columns, but I'd like a flexible way that I don't have to add sublists (cleaned1, 2..) when I fetch more rows.
Any help highly appreciated!!!
MyConnection = MySQLdb.connect( host = "localhost", user = "root", \
passwd = "xxxx", db = "xxxx")
MyCursor = MyConnection.cursor()
**MyList= (File1, File2, File3, File...., File36)
For i in Mylist:
do MYSQL query**
SQL = """SELECT a.column1, a.column2, b.column2 FROM **i in MyList** a, table2 b WHERE
a.column1=b.column1;"""
SQLLen = MyCursor.execute(SQL) # returns the number of records retrieved
AllOut = MyCursor.fetchall()
**List = list(AllOut) # this puts all the TUple information into a list
cleaned = [i[0] for i in List] # this cleans up the Tuple characters)
cleaned1 = [i[1] for i in List] # this cleans up the Tuple characters)
cleaned2 = [i[2] for i in List] # this cleans up the Tuple characters)
NewList=zip(cleaned,cleaned1,cleaned2) # This makes a new List
print NewList[0:10]**
# Close the files
MyCursor.close()
MyConnection.close()
I can figure out the saving to file, but I don't know how to pass a python variable into MYSQL.
convert the tuple to a list first: using
MyList = list(MyList)
and you will have two options:
try this:
for tablename in MyList:
c.execute("SELECT a.column1, a.column2, b.column2 FROM %s a, table2 b WHERE a.column1=b.column1", (tablename))
or :
for tablename in MyList:
SQL= "SELECT a.column1, a.column2, b.column2 FROM tablevar a, table2 b WHERE a.column1=b.column1"
SQL = SQL.replace('tablevar', tablename)
c.execute(SQL)
to print the results without the brackets you can use :
for tablename in MyList:
print tablename