Python: 无法使用 tinydb 读取 json-文件

Python: cannot read json-file with tinydb

我有以下 json- 文件:

tag.tg

[{"_type": "tag", "name": "A0", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    float32_t A0;          \/**< The derived gain, A0 = Kp + Ki + Kd . *\/$/", "typeref": "float32_t", "kind": "member", "scope": "__anond9a59aba0f08", "scopeKind": "struct"},
{"_type": "tag", "name": "A0", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q15_t A0;           \/**< The derived gain, A0 = Kp + Ki + Kd . *\/$/", "typeref": "q15_t", "kind": "member", "scope": "__anond9a59aba0d08", "scopeKind": "struct"},
{"_type": "tag", "name": "A0", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q31_t A0;            \/**< The derived gain, A0 = Kp + Ki + Kd . *\/$/", "typeref": "q31_t", "kind": "member", "scope": "__anond9a59aba0e08", "scopeKind": "struct"},
{"_type": "tag", "name": "A1", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    float32_t A1;          \/**< The derived gain, A1 = -Kp - 2Kd. *\/$/", "typeref": "float32_t", "kind": "member", "scope": "__anond9a59aba0f08", "scopeKind": "struct"},
{"_type": "tag", "name": "A1", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q15_t A1;$/", "typeref": "q15_t", "kind": "member", "scope": "__anond9a59aba0d08", "scopeKind": "struct"},
{"_type": "tag", "name": "A1", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q31_t A1;            \/**< The derived gain, A1 = -Kp - 2Kd. *\/$/", "typeref": "q31_t", "kind": "member", "scope": "__anond9a59aba0e08", "scopeKind": "struct"},
{"_type": "tag", "name": "A1", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q31_t A1;           \/**< The derived gain A1 = -Kp - 2Kd | Kd.*\/$/", "typeref": "q31_t", "kind": "member", "scope": "__anond9a59aba0d08", "scopeKind": "struct"},
{"_type": "tag", "name": "A2", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    float32_t A2;          \/**< The derived gain, A2 = Kd . *\/$/", "typeref": "float32_t", "kind": "member", "scope": "__anond9a59aba0f08", "scopeKind": "struct"},
{"_type": "tag", "name": "A2", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q15_t A2;$/", "typeref": "q15_t", "kind": "member", "scope": "__anond9a59aba0d08", "scopeKind": "struct"},
{"_type": "tag", "name": "A2", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q31_t A2;            \/**< The derived gain, A2 = Kd . *\/$/", "typeref": "q31_t", "kind": "member", "scope": "__anond9a59aba0e08", "scopeKind": "struct"},
{"_type": "tag", "name": "ABFSR", "path": "Drivers\CMSIS\Include\core_cm7.h", "pattern": "/^  __IOM uint32_t ABFSR;                  \/*!< Offset: 0x2A8 (R\/W)  Auxiliary Bus Fault Status /", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anoncee350000a08", "scopeKind": "struct"},
{"_type": "tag", "name": "ABR", "path": "Drivers\CMSIS\Device\ST\STM32F7xx\Include\stm32f767xx.h", "pattern": "/^  __IO uint32_t ABR;      \/*!< QUADSPI Alternate Bytes register,                   Address offs/", "typeref": "__IO uint32_t", "kind": "member", "scope": "__anonea3271f52708", "scopeKind": "struct"},
{"_type": "tag", "name": "ACPR", "path": "Drivers\CMSIS\Include\core_cm3.h", "pattern": "/^  __IOM uint32_t ACPR;                   \/*!< Offset: 0x010 (R\/W)  Asynchronous Clock Prescale/", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anoncee33efc1008", "scopeKind": "struct"},
{"_type": "tag", "name": "ACPR", "path": "Drivers\CMSIS\Include\core_cm4.h", "pattern": "/^  __IOM uint32_t ACPR;                   \/*!< Offset: 0x010 (R\/W)  Asynchronous Clock Prescale/", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anoncee3433d1008", "scopeKind": "struct"},
{"_type": "tag", "name": "ACPR", "path": "Drivers\CMSIS\Include\core_cm7.h", "pattern": "/^  __IOM uint32_t ACPR;                   \/*!< Offset: 0x010 (R\/W)  Asynchronous Clock Prescale/", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anoncee350001008", "scopeKind": "struct"},
{"_type": "tag", "name": "ACPR", "path": "Drivers\CMSIS\Include\core_sc300.h", "pattern": "/^  __IOM uint32_t ACPR;                   \/*!< Offset: 0x010 (R\/W)  Asynchronous Clock Prescale/", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anonccff54a21008", "scopeKind": "struct"},
{"_type": "tag", "name": "ACR", "path": "Drivers\CMSIS\Device\ST\STM32F7xx\Include\stm32f767xx.h", "pattern": "/^  __IO uint32_t ACR;      \/*!< FLASH access control register,     Address offset: 0x00 *\/$/", "typeref": "__IO uint32_t", "kind": "member", "scope": "__anonea3271f51408", "scopeKind": "struct"}
]

我检查了 https://jsonlint.com/ 上 json 文件的有效性,看起来没问题。现在,我正在尝试将 json 文件加载到 Python:

中的 TinyDB 数据库中
from tinydb import TinyDB, Query

db = TinyDB("tag.tg")
Line = Query()
result = db.search(Line.name == "ADC_CCR_DELAY_2")
print(result)

代码在第二行失败 db = TinyDB("tag.tg")。我收到以下错误:

TypeError: list indices must be integers or slices, not str

我做错了什么?我完全按照 tinydb 文档 https://pypi.python.org/pypi/tinydb:

>>> from tinydb import TinyDB, Query
>>> db = TinyDB('/path/to/db.json')

注:
我正在使用 Python 3.6.1

TinyDB 需要索引的 table 文档,而不是列表。除非您想为您的 TinyDB 编写自定义中间件,否则您要么必须将 JSON 修改为:

{
  "_default":{
    "1": {"_type": "tag", "name": "A0", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    float32_t A0;          \/**< The derived gain, A0 = Kp + Ki + Kd . *\/$/", "typeref": "float32_t", "kind": "member", "scope": "__anond9a59aba0f08", "scopeKind": "struct"},
    "2": {"_type": "tag", "name": "A0", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q15_t A0;           \/**< The derived gain, A0 = Kp + Ki + Kd . *\/$/", "typeref": "q15_t", "kind": "member", "scope": "__anond9a59aba0d08", "scopeKind": "struct"},
    "3": {"_type": "tag", "name": "A0", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q31_t A0;            \/**< The derived gain, A0 = Kp + Ki + Kd . *\/$/", "typeref": "q31_t", "kind": "member", "scope": "__anond9a59aba0e08", "scopeKind": "struct"},
    "4": {"_type": "tag", "name": "A1", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    float32_t A1;          \/**< The derived gain, A1 = -Kp - 2Kd. *\/$/", "typeref": "float32_t", "kind": "member", "scope": "__anond9a59aba0f08", "scopeKind": "struct"},
    "5": {"_type": "tag", "name": "A1", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q15_t A1;$/", "typeref": "q15_t", "kind": "member", "scope": "__anond9a59aba0d08", "scopeKind": "struct"},
    "6": {"_type": "tag", "name": "A1", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q31_t A1;            \/**< The derived gain, A1 = -Kp - 2Kd. *\/$/", "typeref": "q31_t", "kind": "member", "scope": "__anond9a59aba0e08", "scopeKind": "struct"},
    "7": {"_type": "tag", "name": "A1", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q31_t A1;           \/**< The derived gain A1 = -Kp - 2Kd | Kd.*\/$/", "typeref": "q31_t", "kind": "member", "scope": "__anond9a59aba0d08", "scopeKind": "struct"},
    "8": {"_type": "tag", "name": "A2", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    float32_t A2;          \/**< The derived gain, A2 = Kd . *\/$/", "typeref": "float32_t", "kind": "member", "scope": "__anond9a59aba0f08", "scopeKind": "struct"},
    "9": {"_type": "tag", "name": "A2", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q15_t A2;$/", "typeref": "q15_t", "kind": "member", "scope": "__anond9a59aba0d08", "scopeKind": "struct"},
    "10": {"_type": "tag", "name": "A2", "path": "Drivers\CMSIS\Include\arm_math.h", "pattern": "/^    q31_t A2;            \/**< The derived gain, A2 = Kd . *\/$/", "typeref": "q31_t", "kind": "member", "scope": "__anond9a59aba0e08", "scopeKind": "struct"},
    "11": {"_type": "tag", "name": "ABFSR", "path": "Drivers\CMSIS\Include\core_cm7.h", "pattern": "/^  __IOM uint32_t ABFSR;                  \/*!< Offset: 0x2A8 (R\/W)  Auxiliary Bus Fault Status /", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anoncee350000a08", "scopeKind": "struct"},
    "12": {"_type": "tag", "name": "ABR", "path": "Drivers\CMSIS\Device\ST\STM32F7xx\Include\stm32f767xx.h", "pattern": "/^  __IO uint32_t ABR;      \/*!< QUADSPI Alternate Bytes register,                   Address offs/", "typeref": "__IO uint32_t", "kind": "member", "scope": "__anonea3271f52708", "scopeKind": "struct"},
    "13": {"_type": "tag", "name": "ACPR", "path": "Drivers\CMSIS\Include\core_cm3.h", "pattern": "/^  __IOM uint32_t ACPR;                   \/*!< Offset: 0x010 (R\/W)  Asynchronous Clock Prescale/", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anoncee33efc1008", "scopeKind": "struct"},
    "14": {"_type": "tag", "name": "ACPR", "path": "Drivers\CMSIS\Include\core_cm4.h", "pattern": "/^  __IOM uint32_t ACPR;                   \/*!< Offset: 0x010 (R\/W)  Asynchronous Clock Prescale/", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anoncee3433d1008", "scopeKind": "struct"},
    "15": {"_type": "tag", "name": "ACPR", "path": "Drivers\CMSIS\Include\core_cm7.h", "pattern": "/^  __IOM uint32_t ACPR;                   \/*!< Offset: 0x010 (R\/W)  Asynchronous Clock Prescale/", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anoncee350001008", "scopeKind": "struct"},
    "16": {"_type": "tag", "name": "ACPR", "path": "Drivers\CMSIS\Include\core_sc300.h", "pattern": "/^  __IOM uint32_t ACPR;                   \/*!< Offset: 0x010 (R\/W)  Asynchronous Clock Prescale/", "typeref": "__IOM uint32_t", "kind": "member", "scope": "__anonccff54a21008", "scopeKind": "struct"},
    "17": {"_type": "tag", "name": "ACR", "path": "Drivers\CMSIS\Device\ST\STM32F7xx\Include\stm32f767xx.h", "pattern": "/^  __IO uint32_t ACR;      \/*!< FLASH access control register,     Address offset: 0x00 *\/$/", "typeref": "__IO uint32_t", "kind": "member", "scope": "__anonea3271f51408", "scopeKind": "struct"}
  }
}

或者为您的现有数据编写自定义 'importer':

import json
import tinydb

db = tinydb.TinyDB("db_storage.json")  # create a new storage for the database

with open("tag.tg", "r") as f:  # open the unmodified `tag.tg`
    json_data = json.load(f)  # parse its JSON

for entry in json_data:  # iterate over each entry in the `tag.tg`
    db.insert(entry)  # insert it in the DB

更新:一些额外的信息,虽然有点超出了这个问题的范围。

正如我在评论中建议的那样,如果您打算使用大量 records/data,使用更优化的数据库可能是更好的主意。如果您需要使用 Python 本身交付的自封装端,SQLite 是一个不错的选择,但请记住它是一个 SQL 数据库而不是文档存储,因此您需要构建您的首先是架构,因此基于您的数据:

import sqlite3

connection = sqlite3.connect("db_store.sqlite")  # 'connect' to the db_store.sqlite

cursor = connection.cursor()  # get a cursor
cursor.execute("""
    CREATE TABLE IF NOT EXISTS main
    (_type TEXT, name TEXT, path TEXT, pattern TEXT,
    typeref TEXT, kind TEXT, scope TEXT, scopeKind TEXT)
""")  # create `main` table if it doesn't exist

然后你可以使用与 TinyDB 类似的方法来插入你的 tag.tg JSON - 加载它,解析它,插入它的项目:

import json

# load and parse the `tag.tg`
with open("tag.tg", "r") as f:  # open the unmodified `tag.tg`
    json_data = json.load(f)  # parse its JSON

# fields that we're interested in, you can omit some if you don't want them in the DB
fields = ("_type", "name", "path", "pattern", "typeref", "kind", "scope", "scopeKind")
# prepare the insert query
query = "INSERT INTO main ({}) VALUES ({})".format(",".join(fields),
                                                   ",".join(("?",) * len(fields)))
# now let's add the records to the SQLite table:
cursor = connection.cursor()  # get a cursor
cursor.executemany(query, ([e.get(field, None) for field in fields] for e in json_data))

现在您可以执行以下操作:

cursor = connection.cursor()  # get a cursor
cursor.execute("SELECT path FROM main WHERE name = 'ABFSR'")  # a generic SQL SELECT
path, = cursor.fetchone()  # get the first result
print("Path: " + path)  # Path: Drivers\CMSIS\Include\core_cm7.h

它肯定能够处理比 TinyDB 多得多的记录,唯一的问题可能是导入您的初始 JSON 数据 - 如果您的系统无法处理整个 [=38] 的加载和解析=] 结构你可能想要寻找流式 JSON 解析器,尽管如果你所有的数据都是按照你所显示的结构(每行一个不同的 JSON 对象)可能需要一个通过删除周围的 [] 以及逗号分隔符并逐行读取和解析文件来解决它。