在Python中插入sqlite 3时的OperationalError

时间:2013-08-28 20:39:55

标签: python sql sqlite

我正在使用我从JSON解析的数据填充数据库。当我执行INSERT语句时,出现错误:sqlite3.OperationalError: no such column: None。一些JSON数据返回null,这将导致Python将None插入表中,但我相信这应该没问题?有谁知道问题是什么?

回溯:     Traceback (most recent call last): File "productInfoScraper.py", line 71, in <module> ")")

我在Python中的INSERT语句:

cursor.execute("INSERT INTO ProductInfo VALUES(" +
        str(data["data"]["product_id"]) + ", " +
        "'" + str(data["data"]["product_name"]) + "'" + ", " +
        "'" + str(data["data"]["ingredients"]) + "'" + ", " +
        "'" + str(data["data"]["serving_size"]) + "'" + ", " +
        str(data["data"]["calories"]) + ", " +
        str(data["data"]["total_fat_g"]) + ", " +
        str(data["data"]["total_fat_percent"]) + ", " +
        str(data["data"]["fat_saturated_g"]) + ", " +
        str(data["data"]["fat_saturated_percent"]) + ", " +
        str(data["data"]["fat_trans_g"]) + ", " +
        str(data["data"]["fat_trans_percent"]) + ", " +
        str(data["data"]["cholesterol_mg"]) + ", " +
        str(data["data"]["sodium_mg"]) + ", " +
        str(data["data"]["sodium_percent"]) + ", " +
        str(data["data"]["carbo_g"]) + ", " +
        str(data["data"]["carbo_percent"]) + ", " +
        str(data["data"]["carbo_fibre_g"]) + ", " +
        str(data["data"]["carbo_fibre_percent"]) + ", " +
        str(data["data"]["carbo_sugars_g"]) + ", " +
        str(data["data"]["protein_g"]) + ", " +
        str(data["data"]["vitamin_a_percent"]) + ", " +
        str(data["data"]["vitamin_c_percent"]) + ", " +
        str(data["data"]["calcium_percent"]) + ", " +
        str(data["data"]["iron_percent"]) + ", " +
        "'" + str(data["data"]["micro_nutrients"]) + "'" +  ", " +
        "'" + str(data["data"]["tips"]) + "'" + ", " +
        str(data["data"]["diet_id"]) + ", " +
        "'" + str(data["data"]["diet_type"]) + "'" +
        ")")

我的CREATE TABLE声明:

cursor.execute("CREATE TABLE ProductInfo(product_id INT, product_name TEXT,\
  ingredients TEXT, serving_size TEXT, calories INT, total_fat_g INT,\
  total_fat_percent INT, fat_saturated_g INT, fat_saturated_percent INT,\
  fat_trans_g INT, fat_trans_percent INT, cholesterol_mg INT, sodium_mg\
  INT, sodium_percent INT, carbo_g INT, carbo_percent INT, carbo_fibre_g\
  INT, carbo_fibre_percent INT, carbo_sugars_g INT, protein_g INT,\
  vitamin_a_percent INT, vitamin_c_percent INT, calcium_percent INT,\
  iron_percent INT, micro_nutrients TEXT, tips TEXT, diet_id INT, diet_type\
  TEXT)")

1 个答案:

答案 0 :(得分:2)

首先,您不应该以这种方式构建SQL语句。正如the documentation明确说:

  

通常,您的SQL操作需要使用Python变量中的值。你不应该使用Python的字符串操作来组装你的查询,因为这样做是不安全的;它使您的程序容易受到SQL注入攻击(请参阅http://xkcd.com/327/以获取可能出错的幽默示例)。

     

相反,请使用DB-API的参数替换。

除了安全问题之外还有其他问题 - 很难让引用和转换正确,很容易在某处犯一个简单的错误,并且很难在制作错误时调试这些错误。

执行此操作的正确方法是为每个键使用命名占位符,并将data["data"]作为参数映射传递:

cursor.execute("""INSERT INTO ProductInfo VALUES(
    :product_id, 
    :product_name,
    ...
    :diet_type)""", data["data"])

我不知道如果没有足够的示例代码和数据来测试它是否会解决您的问题,但它会消除许多潜在的错误来源,所以我会给它很好的赔率。

最可能的问题是,您尝试插入并且未用引号str(data["data"]["sodium_mg"])包装的值之一是Python None值。

将不带引号的None放入SQL语句意味着您要将名为“None”的列的值复制到此列。如果要使用空值或字符串“None”或其他内容,则必须正确编写。

参数绑定将通过插入空值自动为您处理。

但这只是我所说的“难以引用和转换正确”的一个例子,所以我不能确定它正是你所看到的那个。