用Python生成SQL语句

19 投票
5 回答
61155 浏览
提问于 2025-04-15 15:03

我需要从HTML文件中生成一系列插入语句(用于PostgreSQL),请问有没有适合Python的库,可以帮助我正确处理名称和数值的转义和引用?在PHP中,我使用PDO来进行转义和引用,Python有没有类似的库呢?

补充说明:我需要生成一个包含SQL语句的文件,以便后续执行。

5 个回答

2

为了提高安全性,我建议无论你使用什么编程语言,都要使用预处理语句来发送用户输入的值。:-)

15

SQLAlchemy 提供了一种强大的表达语言,可以让你用 Python 生成 SQL 语句。

不过,就像其他设计良好的抽象层一样,它生成的查询会通过绑定变量来插入数据,而不是把查询语言和要插入的数据混合成一个字符串。这种做法可以避免很多严重的安全漏洞,而且从各方面来看都是正确的做法。

30

我知道这个问题有点老了,但我常常想要的东西似乎和提问者想要的一样:一个非常简单的库,用来生成基本的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(对象关系映射)很容易,但你只能看到你输入的内容——你得自己处理输入的安全性 :)

编辑

我仍在使用我之前的库。最近我稍微更新了一下: https://github.com/kokke/nano-ORM-py

撰写回答