2

我正在编写一个小 Python 脚本来帮助我为我的个人项目自动创建 mysql 数据库和相关帐户。该脚本的一部分是一个函数,它将数据库名称作为字符串,然后去创建数据库。

def createDB(dbConn, dbName):
    import MySQLdb
    c = dbConn.cursor()
    query = """CREATE DATABASE %s;""";
    c.execute(query, (dbName,))

这不起作用,因为MySQL 的 CREATE DATABASE要求数据库的不带引号的名称,如

  CREATE DATAbASE test_db

但是我尝试将用户提供的数据库名称安全地插入到查询中的代码会创建:

  CREATE DATABASE 'test_db'

你会得到“你的 MySQL 语法在测试附近有问题”。

即使这是供个人使用,我真的不想直接将用户提供的字符串插入到任何类型的查询中。它反对我的宗教。是否有一种安全的方法可以将用户提供的数据库名称插入到 python(或任何语言)中的 mySQL 查询中,以确保用户输入(例如test_db; DROP some_other_db;将被拒绝或正确转义)?

4

2 回答 2

5

数据库名称(也不是列名或表名)不是数据值,因此不适合使用占位符。想要这样做通常是一个不好的迹象;只有 DBA 才能发出 a create database,因为这样做需要一些相当大的特权。大多数应用程序需要 DBA 发出创建数据库,然后将创建的数据库作为参数用于 dbapi.Connection 的参数中。

如果你确定你需要这个,你信任输入的来源,并且你已经检查了输入是否有无效字符,你只需在 python 中进行替换,例如:

def createDB(dbConn, dbName):
    c = dbConn.cursor()
    query = """CREATE DATABASE %s;""" % dbName
    c.execute(query)
于 2011-07-11T21:27:11.317 回答
2

经过一番挖掘,事实证明 phpmyadmin 使用反引号来引用数据库、表和列名。他们只是这样做:

$sql_query = 'CREATE DATABASE ' . PMA_backquote($new_db);  

这会在上面的错误情况下给出类似

CREATE DATABASE `test_db; DROP some_other_db`;

当然,输入字符串中的任何反引号都需要转义,根据 phpmyadmin 的代码,这是通过将所有单反引号替换为双反引号来完成的。我找不到任何可以确认这是正确的地方。

我也在网上注意到反引号不是标准 SQL。

于 2011-07-12T14:19:03.320 回答