我需要从html文件生成一个insert语句列表(对于postgresql),是否有可用于python的库来帮助我正确转义并引用名称/值?在PHP中,我使用PDO进行转义和引用,是否有任何等效的python库?
编辑:我需要生成一个带有sql语句的文件,以便稍后执行
答案 0 :(得分:19)
我知道这是一个老问题,但我经常想要OP想要的东西:一个非常简单的库,用于生成基本的SQL。
以下功能就是这样做的。您为它们提供了一个表名和一个包含您要使用的数据的字典,它们会返回您需要的操作的SQL查询。
键/值对表示数据库行中的字段名称和值。
def read(table, **kwargs):
""" Generates SQL for a SELECT statement matching the kwargs passed. """
sql = list()
sql.append("SELECT * FROM %s " % table)
if kwargs:
sql.append("WHERE " + " AND ".join("%s = '%s'" % (k, v) for k, v in kwargs.iteritems()))
sql.append(";")
return "".join(sql)
def upsert(table, **kwargs):
""" update/insert rows into objects table (update if the row already exists)
given the key-value pairs in kwargs """
keys = ["%s" % k for k in kwargs]
values = ["'%s'" % v for v in kwargs.values()]
sql = list()
sql.append("INSERT INTO %s (" % table)
sql.append(", ".join(keys))
sql.append(") VALUES (")
sql.append(", ".join(values))
sql.append(") ON DUPLICATE KEY UPDATE ")
sql.append(", ".join("%s = '%s'" % (k, v) for k, v in kwargs.iteritems()))
sql.append(";")
return "".join(sql)
def delete(table, **kwargs):
""" deletes rows from table where **kwargs match """
sql = list()
sql.append("DELETE FROM %s " % table)
sql.append("WHERE " + " AND ".join("%s = '%s'" % (k, v) for k, v in kwargs.iteritems()))
sql.append(";")
return "".join(sql)
你这样使用它。只需给它一个表名和一个字典(或使用python的** kwargs特性):
>>> upsert("tbl", LogID=500, LoggedValue=5)
"INSERT INTO tbl (LogID, LoggedValue) VALUES ('500', '5') ON DUPLICATE KEY UPDATE LogID = '500', LoggedValue = '5';"
>>> read("tbl", **{"username": "morten"})
"SELECT * FROM tbl WHERE username = 'morten';"
>>> read("tbl", **{"user_type": 1, "user_group": "admin"})
"SELECT * FROM tbl WHERE user_type = '1' AND user_group = 'admin';"
但是请注意SQL注入攻击
查看代码的恶意用户执行此操作时会发生什么:
>>> read("tbl", **{"user_group": "admin'; DROP TABLE tbl; --"})
"SELECT * FROM tbl WHERE user_group = 'admin'; DROP TABLE tbl; --';"
制作自己的临时ORM很容易,但你只能得到你所看到的 - 你必须自己逃避输入:)
答案 1 :(得分:10)
SQLAlchemy提供a robust expression language用于从Python生成SQL。
与其他精心设计的抽象层一样,它生成的查询通过绑定变量插入数据,而不是通过尝试将查询语言和插入的数据混合到单个字符串中。这种方法避免了大规模的安全漏洞,而且是正确的事情。
答案 2 :(得分:2)
为了提高稳健性,我建议使用预准备语句发送用户输入的值,无论您使用何种语言。 : - )
答案 3 :(得分:1)
python db api 2.0对连接对象有一个“.execute”方法。您可以使用此函数指定参数(使用逗号而非%符号将params与查询字符串分开)。
答案 4 :(得分:1)
一般手动引用参数是一个坏主意。如果逃避规则有错误怎么办?如果escape与DB的使用版本不匹配怎么办?如果您忘记逃避某些参数或错误地认为它不能包含需要转义的数据,该怎么办?这一切都可能导致SQL注入漏洞。此外,当您需要为LOB列传递大数据块时,DB可能对SQL语句长度有一些限制。这就是为什么Python DB API和大多数数据库(Python DB API模块将透明地转义参数,如果数据库不支持这个,就像早期的MySQLdb那样)允许传递与语句分开的参数:
.execute(操作[,参数])