动态 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 一起使用。
我尝试将数据写入数据库 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 一起使用。