python 列表 mysql in_关于mysql:内嵌要在python MySQLDB IN子句中使用的列表
我知道如何將列表映射到字符串:
foostring =",".join( map(str, list_of_ids) )
而且我知道我可以使用以下命令將該字符串放入IN子句中:
cursor.execute("DELETE FROM foo.bar WHERE baz IN ('%s')" % (foostring))
我需要使用MySQLDB安全地完成同一件事(避免SQL注入)。 在上面的示例中,由于foostring沒有作為執行參數傳遞,因此它很容易受到攻擊。 我還必須在mysql庫之外引用和轉義。
(有一個相關的SO問題,但是那里列出的答案對于MySQLDB無效或容易受到SQL注入的影響。)
您可能可以從php stackoverflow.com/questions/327274/中完成的類似問題中獲得一些啟發
SQL查詢中python列表的可能重復項作為參數
@mluebke關于在查詢中傳遞多個列表的任何想法嗎?
直接使用list_of_ids:
format_strings = ','.join(['%s'] * len(list_of_ids))
cursor.execute("DELETE FROM foo.bar WHERE baz IN (%s)" % format_strings,
tuple(list_of_ids))
這樣,您就不必引用自己的報價,并避免各種SQL注入。
請注意,數據(list_of_ids)作為參數(不在查詢文本中)直接進入mysql的驅動程序,因此沒有注入。您可以在字符串中保留所需的任何字符,而無需刪除或引用字符。
為什么在format_strings中引用%s?也可以通過.execute()方法來處理嗎?
@heikogerlach:我沒有引用%s ...第一行創建了一個字符串"%s,%s,%s" ...的長度與list_of_ids長度相同。
啊,你說的對。需要更加努力。我莫名其妙地把它混合了。不錯的解決方案。
在sqlite中也可以使用嗎?因為我剛嘗試過,它似乎指出了語法錯誤。
在sqlite中,@ Sohaib的替換字符是?而不是%s,因此如果將第一行更改為format_strings = ,.join(? * len(list_of_ids)),它將起作用。
是的,我做了一點研究就知道了。雖然感謝您的幫助:)
根據這樣的語句與不同數量的參數一起使用的頻率,我希望對參數編號進行分組并執行多個以確保數據庫僅看到有限數量的變體(對于sql緩存)。這也有助于避免過多的參數。
您能否為Python3中的相同解決方案提供示例語法?
@nosklo如果使用的查詢對象具有例如fname_list = [item1, item2] query = ("select distinct cln from vcf_commits where branch like %s and repository like %s and filename in (%s) and author not like %s" % format_strings,) cursor = churn_db_connection.get_connection_cursor() cursor.execute(query, (branch, repository, tuple(fname_list), invalid_author,))的參數,如何執行相同操作,則會引發錯誤
@kdas在您的情況下,您不希望% format_strings部分更改查詢中的其他%s占位符,僅更改IN (%s)占位符-實現此目的的方法是將所有%字符加倍,除了所需的字符替換:query = ("select distinct cln from vcf_commits where branch like %%s and repository like %%s and filename in (%s) and author not like %%s" % format_strings,); cursor.execute(query, (branch, repository) + tuple(fname_list) + (invalid_author,))
啊,這真是棒極了@nosklo。 format_strings之后的逗號(,)引起錯誤,但刪除后,它可以正常工作。天才。掌聲。 query = ("select distinct cln from vcf_commits where branch like %%s and repository like %%s and filename in (%s) and author not like %%s" % format_strings);
盡管這個問題已經很老了,但最好還是留下一個答案,以防其他人在尋找我想要的東西
當我們有很多參數或想要使用命名參數時,可接受的答案會變得混亂
經過一番試驗
ids = [5, 3, ...] ?# list of ids
cursor.execute('''
SELECT
...
WHERE
id IN %(ids)s
AND created_at > %(start_dt)s
''', {
'ids': tuple(ids), 'start_dt': '2019-10-31 00:00:00'
})
用python2.7,pymysql==0.7.11測試
如果使用Django 2.0 or 2.1和Python 3.6,這是正確的方法:
from django.db import connection
RESULT_COLS = ['col1', 'col2', 'col3']
RESULT_COLS_STR = ', '.join(['a.'+'`'+i+'`' for i in RESULT_COLS])
QUERY_INDEX = RESULT_COLS[0]
TABLE_NAME = 'test'
search_value = ['ab', 'cd', 'ef'] ?#
query = (
f'SELECT DISTINCT {RESULT_COLS_STR} FROM {TABLE_NAME} a '
f'WHERE a.`{RESULT_COLS[0]}` IN %s '
f'ORDER BY a.`{RESULT_COLS[0]}`;'
) ?#
with connection.cursor() as cursor:
cursor.execute(query, params=[search_value]) ?# params is a list with a list as its element
參考:https://stackoverflow.com/a/23891759/2803344
https://docs.djangoproject.com/zh-CN/2.1/topics/db/sql/#passing-parameters-into-raw
無痛MySQLdb execute('...WHERE name1 = %s AND name2 IN (%s)', value1, values2)
def execute(sql, *values):
assert sql.count('%s') == len(values), (sql, values)
placeholders = []
new_values = []
for value in values:
if isinstance(value, (list, tuple)):
placeholders.append(', '.join(['%s'] * len(value)))
new_values.extend(value)
else:
placeholders.append('%s')
new_values.append(value)
sql = sql % tuple(placeholders)
values = tuple(new_values)
# ... cursor.execute(sql, values)
list_of_ids = [ 1, 2, 3]
query ="select * from table where x in %s" % str(tuple(list_of_ids))
print query
如果您不希望使用必須傳遞參數以完成查詢字符串的方法并且只想調用cursror.execute(query)的方法,則這在某些用例中可能會起作用。
另一種方法可能是:
"select * from table where x in (%s)" % ', '.join(str(id) for id in list_of_ids)
很簡單:只需使用以下格式
rules_id = [" 9"," 10"]
sql1 =" SELECT * FROM Attenance_rules_staff WHERE id in(" +"," .join(map(str,rules_id))+")"
","。join(map(str,rules_id))
它在哪里進行sql引用,這不是使用文字而不是綁定變量嗎?
不需要,它只是工作正常。您可以測試因為元組結構直接用第一個大括號(" 9"," 10")轉換為字符串。哪個調整sql格式。因此,您不需要其他格式即可使sql可調整
并且rules_id是否包含"); DROP TABLES Bobby --?
已經告訴"內嵌列表"而不是")" ...因此在查詢之前,您需要驗證
或使用:sql1 =" SELECT * FROM Attenance_rules_staff WHERE id in(" +"," .join(map(str,rules_id))+")"
如果您堅持使用數字,我猜它很好,但是仍然會產生帶有文字的SQL,糟糕的SQL解析器...
總結
以上是生活随笔為你收集整理的python 列表 mysql in_关于mysql:内嵌要在python MySQLDB IN子句中使用的列表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何定位问题?
- 下一篇: mysql权限说法正确的是,【多选题】下