简体   繁体   English

Python 和使用变量准备的 SQL 语句

[英]Python and Prepared SQL Statements using Variables

I'm fairly new to Python but have a project I am working on so please excuse any nativity on my part.我对 Python 还很陌生,但我正在从事一个项目,所以请原谅我的任何出生。 I am writing some SQL statements in Python 2.7 (Libraries not upgraded to 3 yet) but I am getting stuck on best practice procedure for them.我正在 Python 2.7 中编写一些 SQL 语句(库尚未升级到 3),但我陷入了他们的最佳实践过程。 We are using Sybase.我们正在使用 Sybase。 Initially I was using最初我正在使用

query = "UPDATE DB..TABLE SET version = '{}' WHERE name = '{}'".format(app.version, app.name)
cursor.execute(query)

But realised this after further reading that it is open to injection.但是在进一步阅读后意识到它可以注入。 So I then looked at doing the following:所以我然后看着做以下事情:

query = "UPDATE DB..TABLE SET version = '%s' WHERE name = '%s'" % (app.version, app.name)
cursor.execute(query)

But got me to thinking is this not the same thing?但是让我想到这不是一回事吗?

The parameters are also variables set by argparse, which means I have to use the '' around %s otherwise it throws up the invalid column name error.参数也是由 argparse 设置的变量,这意味着我必须在 %s 周围使用 '' 否则会引发无效列名错误。 Which is frustrating for me as I also want to be able to pass NULL (None in Python) by default if any additional flags aren't set in other queries, otherwise it obviously inserts "NULL" as string.这对我来说令人沮丧,因为如果在其他查询中未设置任何其他标志,我还希望能够默认通过 NULL (Python 中为无),否则它显然会插入“NULL”作为字符串。

For this particular example the 2 variables are set from a file being read by ConfigParser but I think it's still the same for argparse variables.对于这个特定示例,2 个变量是从 ConfigParser 读取的文件中设置的,但我认为 argparse 变量仍然相同。 eg例如

[SECTION]
application=name
version=1.0

I'm not quite sure how to best tackle this issue and yes yes I know "PYTHON 3 IS BETTER UPGRADE TO IT", as I said at the start, the libraries are in the process of being ported.我不太确定如何最好地解决这个问题,是的,我知道“PYTHON 3 可以更好地升级到它”,正如我在一开始所说的那样,这些库正在被移植。

If you need any additional info then please advise and I will give you the best I can.如果您需要任何其他信息,请提出建议,我会尽我所能。

UPDATE*** Using the following Param style string I found in some sybase docs it can work but it does not pass None for NULL and throws up errors, starting to think this is a limitation of the sybase module in python.更新*** 使用我在一些 sybase 文档中找到的以下 Param 样式字符串,它可以工作,但它没有通过 NULL 的 None 并引发错误,开始认为这是 python 中 sybase 模块的限制。

cursor.execute("SELECT * FROM DB..table where app_name=@app_name", {"@app_name": app_name})
or
params = {"@appname": app.name. "@appver": app.version}
sql = "INSERT INTO DB..table (app_name, app_version) VALUES (@appname, @appversion)
cursor.execute(sql, params)

There is an issue though if you have a global list of params and feed that to a query that if any are None then it gives you a lot of errors again about being None, EVEN if those specific params aren't used in the query.但是,如果您有一个全局参数列表并将其提供给查询,如果有任何参数为 None ,那么即使在查询中未使用这些特定参数,它也会再次给您很多关于为 None 的错误。 Think I may be stuck doing IF statements for various options here for multiple inserts to bypass this None NULL issue.认为我可能会在这里为多个插入执行各种选项的 IF 语句以绕过此无 NULL 问题。

Ok I have resolved this issue now.好的,我现在已经解决了这个问题。 I had to update the sybase module in order to get it to work with None > NULL.我必须更新 sybase 模块才能使其与 None > NULL 一起工作。

As posted in the updated question.正如在更新的问题中发布的那样。 the below is how I was running the queries.以下是我运行查询的方式。

cursor.execute("SELECT * FROM DB..table where app_name=@app_name", {"@app_name": app_name})
or
params = {"@appname": app.name. "@appver": app.version}
sql = "INSERT INTO DB..table (app_name, app_version) VALUES (@appname, @appversion)
cursor.execute(sql, params)

But got me to thinking is this not the same thing?但是让我想到这不是一回事吗?

Yes, those are effectively the same.是的,这些实际上是相同的。 They are both wide open to an injection attack.它们都对注入攻击持开放态度。

Instead, do it this way:相反,这样做:

query = "UPDATE DB..TABLE SET version = %s WHERE name = %s"
cursor.execute(query, [app.version, app.name])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM