【问题标题】:TypeError: coercing to Unicode: need string or buffer, NoneType foundTypeError:强制转换为 Unicode:需要字符串或缓冲区,找到 NoneType
【发布时间】:2014-07-01 09:33:42
【问题描述】:

我正在尝试从 python 脚本创建一个 SQL 字符串。

这是代码:

sql_query = ('insert into ithelpdesk ' 
        '(id,display_id,subject,description,priority,status,requester_name,source,responder_id,due_by,updated_at,frDueBy,ticket_type,created_at)'
        ' values ('
        '"' + str(data['id']) + '",'
        '"' + str(data['display_id']) + '",'
        '"' + data['subject'] + '",'
        '"' + data['description'] + '",'
        '"' + str(data['priority']) + '",'
        '"' + str(data['status']) + '",'
        '"' + data['requester_name'] + '",'
        '"' + str(data['source']) + '",'
        '"' + str(data['responder_id']) + '",'
        '"' + str(data['due_by']) + '",'
        '"' + str(data['updated_at']) + '",'
        '"' + str(data['frDueBy']) + '",'
        '"' + data['ticket_type'] + '",'
        '"' + str(data['created_at']) + '"'
        ')')

当我运行时,我会收到这条回溯消息:

Traceback (most recent call last):
 File "c:\users\swatson\dropbox\source files\winpython\dash\newTickets.py", line 198, in <module>
main()
 File "c:\users\swatson\dropbox\source files\winpython\dash\newTickets.py", line 159, in main
addNew(n)
File "c:\users\swatson\dropbox\source files\winpython\dash\newTickets.py", line 65, in addNew
'"' + str(data['created_at']) + '"'
TypeError: coercing to Unicode: need string or buffer, NoneType found

现在我知道一个事实(通过执行 printstr(data['created_at'])),data['created_at'] 有一个值,我也知道它与 data[ 'updated_at'] 所以我不知道如何解决这个问题?

【问题讨论】:

    标签: python python-2.7 unicode


    【解决方案1】:

    您的基本错误是尝试将查询构建为一个字符串。 不要这样做。 SQL 注入漏洞就是这样存在的。

    改用 SQL 参数:

    sql_query = ('insert into ithelpdesk ' 
            '(id,display_id,subject,description,priority,status,requester_name,source,responder_id,due_by,updated_at,frDueBy,ticket_type,created_at)'
            ' values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
        (data['id'], data['display_id'], data['subject'], data['description'],
         data['priority'], data['status'], data['requester_name'], data['source'], 
         data['responder_id'], data['due_by'], data['updated_at'], data['frDueBy'],
         data['ticket_type'], data['created_at']))
    

    确切的语法取决于您的数据库适配器;可能你需要使用%s。许多数据库适配器还支持 named 参数,在这种情况下,您甚至不需要传入 15 个单独的值。您只需在查询中命名要从字典中提取的键:

    sql_query = ('insert into ithelpdesk ' 
            '(id,display_id,subject,description,priority,status,requester_name,source,responder_id,due_by,updated_at,frDueBy,ticket_type,created_at)'
            ' values (:id, :display_id, :subject, :description, '
            '         :priority, :status, :requester_name, :source '
            '         :responder_id, :due_by, :updated_at, :frDueBy, '
            '         :ticket_type, :created_at)',
        data)
    

    Python DB API standard 支持几种不同的参数样式。对于位置参数,可以使用?%s,对于命名,:name%(name)ssqlite3 使用第一种样式,MySQLDB the latter

    抛出异常,您正在将 unicode 数据与字符串数据连接起来,并且某处有一个 None。也许data['ticket_type']None

    【讨论】:

    • @Stevo_300:MySQLDB 使用%s 而不是? 用于SQL 参数。不确定它是否支持命名。
    • @Stevo_300:MySQLDB支持%(name)s样式参数,所以你的代码可以使用%(id)s, %(display_id)s, %(subject)s
    猜你喜欢
    • 2014-12-21
    • 1970-01-01
    • 2012-06-06
    • 2019-04-02
    • 1970-01-01
    • 2021-03-28
    • 2015-02-01
    • 1970-01-01
    相关资源
    最近更新 更多