动态 table mysqldb python string/int 问题

dynamic table mysqldb python string/int issue

我尝试将数据写入数据库 table 时收到一个错误,当我使用一个变量作为 table 名称时,我在使用静态名称时没有得到。出于某种原因,在我插入的行中,如果我插入一个整数作为代码运行的列值并且 table 被填充,但是,如果我尝试使用字符串,我会得到 SQL 语法错误

cursor = db.cursor()
cursor.execute('DROP TABLE IF EXISTS %s' %data[1])

sql ="""CREATE TABLE %s  (IP TEXT, AVAILIBILITY INT)""" %data[1]
cursor.execute(sql)

for key in data[0]:
    cur_ip = key.split(".")[3]
    cursor.execute("""INSERT INTO %s VALUES (%s,%s)""" %(data[1],key,data[0][key]))  
    db.commit()

问题是我有什么想法%(data[1], key, data[0][key])

如果您没有 post 实际错误,那么分析您的问题有点困难,因为我们必须猜测您的数据实际是什么。但建议的一些一般要点:

使用动态 table 名称通常不是数据库系统希望使用的方式。尝试考虑是否可以通过使用静态 table 名称并向 table 添加额外的键列来解决该问题。在该字段中,您可以将您现在所做的作为动态 table 名称。这样数据库可能能够更好地优化您的查询,并且您的查询不太可能出错(不需要一次创建额外的 tables,这不是一件便宜的事情。而且您不需要动态 DROP TABLE 查询,这可能存在安全风险。

所以我对解决您的问题的建议是通过尝试完全摆脱动态 table 名称来实际解决它。

您遇到的另一个问题是您使用的是 python 字符串格式,而不是查询本身的参数。这本身就是一个安全问题(SQL-注入),也是你语法错误的问题。当您使用数字时,您的表达式计算为

INSERT INTO table_name VALUES (100, 200)

有效 SQL。但是使用字符串你会得到

INSERT INTO table_name VALUES (Some Text, some more text)

这是无效的(因为字符串周围没有引号 '

要摆脱语法问题和 sql 注入问题,请不要将值添加到字符串中,将它们作为列表传递给 execute():

cursor.execute("INSERT INTO table_name VALUES (%s,%s)", (key, data[0][key]))

如果您必须有一个动态的 table 名称,请首先将其放入您的查询字符串中(例如使用 % 格式),然后将您的查询的实际值作为上述参数(因为我无法想象 execute 会接受 table 名称作为参数)。

把它放在一些简单的示例代码中。现在你正在尝试这样做:

# don't do this, this won't even work!
table_name = 'some_table'
user_name = 'Peter Smith'
user_age = 47
query = "INSERT INTO %s VALUES (%s, %s)" % (table_name, user_name, user_age)
cursor.execute(query)

创建查询

INSERT INTO some_table VALUES (Peter Smith, 100)

由于未加引号的字符串,这无法工作。所以你需要做:

# DON'T DO THIS, it's bad!
query = "INSERT INTO %s VALUES ('%s', %s)" % (table_name, user_name, user_age)

这不是一个好主意,因为您需要知道在何处放置引号以及在何处不放置引号(有时您会搞砸)。更糟糕的是,想象一个名为 named Connor O'Neal 的用户。你会得到一个语法错误:

INSERT INTO some_table VALUES ('Connor O'Neal', 100)

(这也是 sql 注入用于破坏您的系统/窃取您的数据的方式)。因此,您还需要注意转义字符串值。越来越复杂了。

将这些问题留给 python 和 mysql,将日期(不是 table 名称)作为参数传递给执行!

table_name = 'some_table'
user_name = 'Peter Smith'
user_age = 47
query = "INSERT INTO " + table_name + " VALUES (%s, %s)"
cursor.execute(query, (user_name, user_age))

这样你甚至可以直接传递 datetime 对象。除了使用 %s 之外,还有其他放置数据的方法,请查看此示例 http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html(即那里使用的 python3,我不知道您使用哪种 - 但除了在 print 语句中,我认为它也应该与 python2 一起使用。