【问题标题】:Insert json data onto sql, keys not same in all the dictionary and some of the keys is not exists将json数据插入sql,所有字典中的键都不相同,并且某些键不存在
【发布时间】:2020-03-24 17:49:17
【问题描述】:

我仍然无法将 mydata 插入 sql。我有搜索但找不到解决方案。我读取了 json 文件并将数据插入到 sql db 中。 json 文件包含多个键/值字典的列表。下面是配置的参数栏 对于数据库表1

+---------------------------+--------------+------+-----+---------+----------------+
| Field                     | Type         | Null | Key | Default | Extra          |
+---------------------------+--------------+------+-----+---------+----------------+
| id                        | int(10)      | NO   | PRI | NULL    | auto_increment |
| log_number                | int(10)      | YES  |     | NULL    |                |
| timestamp                 | datetime     | YES  |     | NULL    |                |
| staff_id                  | varchar(10)  | YES  |     | NULL    |                |
| staff_name                | varchar(30)  | YES  |     | NULL    |                |
| temp_staff_id             | varchar(10)  | YES  |     | NULL    |                |
| temp_staff_name           | varchar(30)  | YES  |     | NULL    |                |
| staff_department          | varchar(20)  | YES  |     | NULL    |                |
| service_id                | varchar(20)  | YES  |     | NULL    |                |
| service_number            | varchar(20)  | YES  |     | NULL    |                |
| state                     | varchar(20)  | YES  |     | NULL    |                |
| city                      | varchar(20)  | YES  |     | NULL    |                |
| description               | varchar(50)  | YES  |     | NULL    |                |
| additional_remarks        | varchar(100) | YES  |     | NULL    |                |
+---------------------------+--------------+------+-----+---------+----------------+

并非所有字典都列出了所有 db 参数。有些没有“州”和“城市”,有些字典没有“附加备注”..有些有“临时员工ID”和“临时员工名称”。总体而言,db中的参数将涵盖需要插入的json文件的不同类型的key/value数据。

下面是需要插入到 db table1 的示例数据

{
  "response": {
   "client_log": {
      "data": [
          {
          "log_number": "1",
          "timestamp": "2020-01-11 04:23:31",
          "staff_id": "A123",
          "staff_name": "Krill",
          "staff_department": "Sales",
          "service_id": "11111",
          "service_number": "BU-11111",
          "description": "This is description1"
         },
         {
          "log_number": "2",
          "timestamp": "2020-01-11 07:03:39",
          "staff_id": "A456",
          "staff_name": "James",
          "staff_department": "Graphic",
          "service_id": "22222",
          "service_number": "XU-22211",
          "State": "AAA",
          "City": "AAA"
         },
         {
          "log_number": "3",
          "timestamp": "2020-01-27 14:29:11",
          "temp_staff_id": "A571",
          "temp_staff_name": "Mary",
          "staff_department": "Engr",
          "service_id": "89000",
          "service_number": "SP-89001",
          "State": "BBB",
          "City": "BBB"
         },
         {
          "log_number": "4",
          "timestamp": "2020-01-27 15:08:20",
          "staff_id": "A765",
          "staff_name": "Alex",
          "staff_department": "Sales",
          "service_id": "09880",
          "service_number": "XU-09880",
          "description": "This is description3333"
         }
      ],
      "query": "4"
    },
  }
}


我正在使用下面的脚本插入数据...我插入了 table1 中可用的所有键..但我得到了错误

with open(myfile, 'r') as f:
   mydata = json.load(f)

#Insert the values onto table1 of db.
sql = "INSERT INTO `table1` (`log_number`, `timestamp`, `staff_id`, `staff_name`, `temp_staff_id`, `temp_staff_name`, `staff_department`, `service_id`, `service_number`, `state`, `city`, `description`, `additional_remarks`) VALUES ( %(log_number)s, %(timestamp)s, %(staff_id)s, %(staff_name)s, %(temp_staff_id)s, %(temp_staff_name)s, %(staff_department)s, %(service_id)s, %(service_number)s, %(state)s, %(city)s, %(description)s, %(additional_remarks)s )"
cursor.executemany( sql, mydata['response']['client_log']['data'])

错误...

1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '%(temp_staff_id)s, %(temp_staff_name)s, 'Sales', '11111', 'BU-11111', %(state)s,' at line 1

如果每个字典的所有键都相同并且存在并且完全遵循数据库的参数,我可以插入数据而不会出现任何错误。

由于 json 文件中的字典键集不相同并且有些不存在...所以,我该如何进行数据插入...例如,如果没有州或城市或附加备注只插入 null。当某些关键参数与其他关键参数不同或不存在时,我不确定该怎么做。我希望你们能帮助并建议我解决方案。谢谢



我已经尝试了 mr rashid 解决方案并在下面返回错误

<class 'dict'> ====> mydata is a dictionary type
{'response': {'client_log': {'data': [{'log_number': '1', 'timestamp': '2020-01-11 04:23:31', 'staff_id': 'A123', 'staff_name': 'Krill', 'staff_department': 'Sales', 'service_id': '11111', 'service_number': 'BU-11111', 'description': 'This is description1'}, {'log_number': '2', 'timestamp': '2020-01-11 07:03:39', 'staff_id': 'A456', 'staff_name': 'James', 'staff_department': 'Graphic', 'service_id': '22222', 'service_number': 'XU-22211', 'State': 'AAA', 'City': 'AAA'}, {'log_number': '3', 'timestamp': '2020-01-27 14:29:11', 'temp_staff_id': 'A571', 'temp_staff_name': 'Mary', 'staff_department': 'Engr', 'service_id': '89000', 'service_number': 'SP-89001', 'State': 'BBB', 'City': 'BBB'}, {'log_number': '4', 'timestamp': '2020-01-27 15:08:20', 'staff_id': 'A765', 'staff_name': 'Alex', 'staff_department': 'Sales', 'service_id': '09880', 'service_number': 'XU-09880', 'description': 'This is description3333'}], 'total_hero_query': '13'}, 'response_time': '0.723494', 'transaction_id': '909122', 'transaction_status': 'OK', 'transaction_time': 'Fri Feb 28 15:27:51 2020'}}
'str' object has no attribute 'keys'

我在下面编辑

for row in json_in['response']['client_log']['data']: 

与密钥相关的错误消失了,但现在与 sql 相关的错误

1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'description1, 2020-01-11 04:23:31, Krill, Sales, BU-11111, 1, 11111),(A123, This' at line 1 

这个错误可能是由于字典数据中的不同键或不存在键,根据我之前的这个线程的问题...... 到目前为止,我真的需要帮助......仍然无法解决问题。请帮我。谢谢。

【问题讨论】:

  • 您需要将dict的键和对应的值添加到每个json条目的sql中,而不是硬编码一段sql。

标签: python mysql json dictionary sql-insert


【解决方案1】:

所以不要硬编码 sql 来拥有每一列。您需要动态构建 sql 语句以获得您拥有的列/值。

这可以通过一个简单的循环来完成。

也不是立即执行插入命令。我将它们放入一个列表中,以便您可以将所有上传线程同时运行。我确实没有编写代码的线程部分,所以你需要这样做。第二个循环需要用线程代码替换,或者如果您不打算使用线程,您可以只执行执行而不是将其附加到 sql_inserts 变量。

编辑:添加 Json 加载。

所以我不完全知道您的数据是如何进入代码的。但原始 json 数据显示为 unicode 字符串。您必须将其格式化为字典。幸运的是,有一个方便的 python 模块可以做到这一点。

所以我们可以只导入 json 模块,然后将数据加载到其中。

另请注意,我在使用变量名时遇到了复制和粘贴错误。

确保任何显示 keys 的代码现在显示为 sql_keys

import json

# This converts the json data into a python dictionary so that python can process it.
json_in = json.loads(mydata)

sql_template = 'INSERT INTO `table1` ({}) VALUES ({})'
sql_inserts = []

for row in json_in:
    sql_keys = row.keys()
    sql_values = []

    for key in sql_keys:
        sql_values.append(row[key])

    # This is the line my copy and paste error was on
    sql_inserts.append(sql_template.format(', '.join(sql_keys), ', '.join(sql_values)))

for insert in sql_inserts:
    cursor.executemany(insert, mydata['response']['client_log']['data'])

这是一种非常简洁易读的方法。如果你真的关心有多少行代码,比如在代码高尔夫的情况下,你可以通过列表理解和/或可能的 lambda 来制作这个排序器。

【讨论】:

  • 嗨...谢谢先生...第一个 for 循环中的 json_in 是我的字典,在这种情况下是 mydata 对吗?我将 json_in 替换为 mydata ...我按照您上面的确切代码并返回错误 ''unicode' object has no attribute 'keys' ...我没有做任何线程...只是为了确保可以插入数据...目前无法插入数据。
  • 所以对于你的 json 对象。你json解码成python了吗? Python本身并不处理json,但是json对象基本上就是一个python字典,所以可以解码。如果您不知道我如何编辑答案并向您展示。
  • 那里更新了。请注意我 json 加载变量 mydata 然后从那时起使用 json_in 的部分。
  • 实际上...... mydata 已经在字典中......我在上面更新了我如何读取 json 并作为字典加载。我已经根据我的回复消息进行了相应的替换,并收到错误 ''unicode' object has no attribute 'keys'...
  • 所有字典都有keys方法。这是python内置的。所以这告诉我数据不是字典。将数据加载到 mydata 并确认其数据类型后,是否下过断点?
猜你喜欢
  • 1970-01-01
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2023-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多