1

I've got the following json-file:

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"}
]

I've checked the validity of the json-file on https://jsonlint.com/, and it looks okay. Right now, I'm trying to load the json-file into a TinyDB database in Python:

from tinydb import TinyDB, Query

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

The code fails at the second line db = TinyDB("tag.tg"). I get the following error:

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

What did I do wrong? I'm exactly following the tinydb docs https://pypi.python.org/pypi/tinydb:

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

Note:
I'm using Python 3.6.1

K.Mulier
  • 8,069
  • 15
  • 79
  • 141

1 Answers1

5

TinyDB expects an indexed table document, not a list. Unless you want to write a custom middleware for your TinyDB, you'll either have to modify your JSON to:

{
  "_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"}
  }
}

Or write a custom 'importer' for your existing data:

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

UPDATE: Some additional info, although going a bit outside of this question's scope.

As I've suggested in the comments, if you intend to use a huge amount of records/data, it might be a better idea to use a more optimized DB. If you need something self-encapsulating end delivered with Python itself, SQLite is not a bad option but remember that it's an SQL database and not a document store so you need to build your schema first, so based on your data:

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

Then you can use a similar approach as with TinyDB to insert your tag.tg JSON - load it, parse it, insert its items:

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))

And now you can do things like:

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

It will certainly be able to handle far more records than TinyDB, the only problematic thing might be importing your initial JSON data - if your system just can't handle loading and parsing the whole JSON structure at once you might want to look out for streaming JSON parsers, although if all of your data is structured as you've shown (a different JSON object on each line) one might take a swing at it by removing the surrounding [ and ] and comma separators and read & parse the file line by line.

zwer
  • 24,943
  • 3
  • 48
  • 66
  • Wonderful! Your custom importer is exactly what I needed. Thank you so much! – K.Mulier Dec 11 '17 at 16:55
  • One problem ... This custom importer is very very slow - I'm now trying it out on a bigger database of 20.000 lines, and still waiting. What would you recommend? – K.Mulier Dec 11 '17 at 17:06
  • 1
    @K.Mulier - JSON isn't exactly a stream friendly format so most parsers will load up the whole file, then parse it as a whole which can take a huge amount of time once you start going into thousands of records. To make matters worse, TinyDB using the default JSON storage will do exactly the same (not to mention serializing and writing the whole JSON file each time you make a change) - it's just not optimized for that kind of a thing. If a large amount of data is your forte, check MongoDB, Redis, Couchbase or any other more performant NoSQL document store. – zwer Dec 11 '17 at 17:43
  • Thank you. How about sqlite3 in Python? – K.Mulier Dec 11 '17 at 18:03
  • 1
    @K.Mulier - much better choice for a large number of records, although it's not a document store so there are restrictions. Check the update above. – zwer Dec 11 '17 at 18:53
  • There is something wrong in the `executemany(...)` function, but I can't figure out what exactly. I get the error message `KeyError: 'typeref'` – K.Mulier Dec 11 '17 at 19:24
  • I think I get why the error appears. Not all my entries have the key `typeref` in the JSON file. – K.Mulier Dec 11 '17 at 19:30
  • @K.Mulier - There is a better way to deal with that. I'll update. – zwer Dec 11 '17 at 19:46
  • Thank you @zwer. I really appreciate that :-) – K.Mulier Dec 11 '17 at 19:47
  • @K.Mulier - there you go, it's a bit slower, what with additional loops and all, but it's far more data tolerant and you can control the fields you want. – zwer Dec 11 '17 at 20:02
  • Great! Thank you – K.Mulier Dec 11 '17 at 20:27