TypeError:强制转换为Unicode:需要字符串或缓冲区,找到NoneType

时间:2014-07-01 09:33:42

标签: python python-2.7 unicode

我正在尝试从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']))数据['created_at']有一个值,我也知道它与数据的值相同[ 'updated_at']所以我不知道如何解决这个问题?

1 个答案:

答案 0 :(得分: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。许多数据库适配器也支持命名的参数,在这种情况下,您甚至不需要传递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