【问题标题】:Python mysql connector prepared INSERT statement cutting off textPython mysql连接器准备INSERT语句切断文本
【发布时间】:2014-07-11 19:36:40
【问题描述】:

我一直在尝试使用 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 自带)

库:MySQL 连接器/Python

【问题讨论】:

  • 如果是mysql请移除sql标签
  • 你使用的是哪个 Python MySQL 库?
  • 我正在使用 mysql.com 上提供的 MySQL 连接器/Python

标签: python mysql prepared-statement


【解决方案1】:

当 MySQL 连接器驱动程序处理准备好的语句时,它使用较低级别的二进制协议将值单独传递给服务器。因此,它告诉服务器这些值是 INT 还是 VARCHAR 还是 TEXT 等。它并不是特别聪明,这种“行为”就是结果。在这种情况下,它看到该值是一​​个 Python 字符串值,并告诉 MySQL 它是一个 VARCHAR 值。 VARCHAR 值具有影响发送到服务器的数据量的字符串长度限制。更糟糕的是,long 值和有限的数据类型长度之间的交互会产生一些奇怪的行为。

最终,您有几个选择:

  1. 为您的字符串使用文件链接对象

    MySQL 连接器将文件和类似文件的对象视为 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()
    
  2. 不要使用 MySQL 连接器准备好的语句

    如果您没有在游标创建语句中使用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()
    
  3. 使用其他 MySQL 驱动程序

    有几个不同的 Python MySQL 驱动程序:

【讨论】:

    猜你喜欢
    • 2011-01-28
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多