我一直在尝试使用pythons mysql.connector将大字符串插入MySQL数据库。我遇到的问题是,在使用预准备语句时,长字符串会在某些时候被切断。我目前正在使用MySQL.com上提供的MySQL Connector / Python。我使用以下代码来复制我遇到的问题。
db = mysql.connector.connect(**creditials)
cursor = db.cursor()
value = []
for x in range(0, 2000):
value.append(str(x+1))
value = " ".join(value)
cursor.execute("""
CREATE TABLE IF NOT EXISTS test (
pid VARCHAR(50),
name VARCHAR(120),
data LONGTEXT,
PRIMARY KEY(pid)
)
""")
db.commit()
#this works as expected
print("Test 1")
cursor.execute("REPLACE INTO test (pid, name, data) VALUES ('try 1', 'Description', '{0}')".format(value))
db.commit()
cursor.close()
#this does not work
print("Test 2")
cursor = db.cursor(prepared=True)
cursor.execute("""REPLACE INTO test (pid, name, data) VALUE (?, ?, ?)""", ('try 2', 'Description2', value))
db.commit()
cursor.close()
测试1按预期工作并存储所有数字到2000,但测试2在数字65之后立即被切断。我宁愿使用预备语句而不是尝试自己清理传入的字符串。任何帮助表示赞赏。
额外信息:
计算机:Windows 7 64位
Python:尝试使用python 3.4和3.3
MYSQL:5.6.17(与WAMP合作)
Library:MySQL Connector / Python
答案 0 :(得分:4)
当MySQL Connector驱动程序处理预处理语句时,它使用较低级别的二进制协议将值分别传递给服务器。因此,它告诉服务器值是INT还是VARCHAR还是TEXT等。它并不是特别聪明,而这种“行为”就是结果。在这种情况下,它看到该值是一个Python字符串值,并告诉MySQL它是一个VARCHAR值。 VARCHAR值具有字符串长度限制,该限制会影响发送到服务器的数据量。更糟糕的是,长值和有限数据类型长度之间的相互作用会产生一些奇怪的行为。
最终,您有几个选择:
为字符串
使用文件链接对象MySQL Connector将文件和类文件对象视为BLOB和TEXT(取决于文件是分别以二进制还是非二进制模式打开)。您可以利用它来获得您想要的行为。
import StringIO
...
cursor = db.cursor(prepared=True)
cursor.execute("""REPLACE INTO test (pid, name, data) VALUES (?, ?, ?)""",
('try 2', 'Description', StringIO.String(value)))
cursor.close()
db.commit()
不要使用MySQL Connector预处理语句
如果不对游标创建语句使用prepared=True
子句,它将为每次执行生成完整的有效SQL语句。在这种情况下避免使用MySQL预处理语句,你并没有真正失去太多。您需要以稍微不同的形式传递SQL语句,以获得正确的占位符清理行为。
cursor = db.cursor()
cursor.execute("""REPLACE INTO test (pid, name, data) VALUES (%s, %s, %s)""",
('try 2', 'Description', value))
cursor.close()
db.commit()
使用其他MySQL驱动程序
有几种不同的Python MySQL驱动程序: