Восстановите строку базы данных с плохой структурой в Json - PullRequest
0 голосов
/ 09 февраля 2020

Мне нужно восстановить базу данных в python, у меня много строк, которые написаны в плохом json.

Вот пример моей базы данных в json:

{ 
  "name":"Nazamiu0304 Rau0304majiu0304",
  "personal_name":"Nazamiu0304 Rau0304majiu0304",
  "last_modified":{ 
    "type":"/type/datetime",
    "value":"2008-08-20T18:00:41.270799"
  },
  "key":"/authors/OL1001461A",
  "type":{ 
    "key":"/type/author"
  },
  "revision":2
}
{ 
  "name":"Harald A. Enge",
  "personal_name":"Harald A. Enge",
  "created":{ 
    "type":"/type/datetime",
    "value":"2008-04-01T03:28:50.625462"
  },
  "alternate_names":[ 
    "Harald A Enge"
  ],
  "last_modified":{ 
    "type":"/type/datetime",
    "value":"2013-02-25T09:47:06.574533"
  },
  "latest_revision":3,
  "key":"/authors/OL1001542A",
  "type":{ 
    "key":"/type/author"
  },
  "revision":3
}

Как вы можете видеть, это не совсем json, поэтому в python я прибыл, чтобы восстановить всю строку, как если это было json спасибо, метод разбора и с пакетным кодом тоже ..

Но проблема в том, что у меня не всегда одинаковая структура с именами, personal_name, last_modifier .... иногда у меня есть другие такие данные, как death_date, bio ... Я могу восстановить всю базу данных, кроме случаев, когда информация "bio" находится здесь.

Я показываю вам:

{ 
  "bio":{ 
    "type":"/type/text",
    "value":"> "Eversley, William Pinder, B.C.L. Queen's Coll., Oxon, M.A., a member of the South-eastern circuit, reporter for Law Times in Queen's Bench division, a student of the Inner Temple 14 April, 1874 (then aged 23), called to the bar 25 April, 1877 (eldest son of William Eversley, Esq., of London); born u2060, 1851. rn> rn> 7, King's Bench Walk, Temple, E.C." rn> ...[in Foster's Men at the Bar][1]rnrnrn rnrn[1]: https://en.wikisource.org/wiki/Men-at-the-Bar/Eversley,_William_Pinder "Men at the Bar""
  },
  "name":"William Pinder Eversley",
  "created":{ 
    "type":"/type/datetime",
    "value":"2008-04-01T03:28:50.625462"
  },
  "death_date":"1918",
  "photos":[ 
    6897255,
    6897254
  ],
  "last_modified":{ 
    "type":"/type/datetime",
    "value":"2018-07-31T15:39:07.982159"
  },
  "latest_revision":6,
  "key":"/authors/OL1003081A",
  "birth_date":"1851",
  "personal_name":"William Pinder Eversley",
  "type":{ 
    "key":"/type/author"
  },
  "revision":6
}

С моим кодом в python, Я не могу восстановить строку "bio": {.....}, поэтому я сделал все oop, которые берут всю строку (name_personal_name ... кроме bio).

Я много пробовал вещи, чтобы восстановить строку био.

Сначала я попытался поменять 'per`, как для Queen за пример, поэтому, когда я сделал это в пакетном режиме, это работает, но я получил другую ошибку со значением: <</p>

Я показываю вам свой код:

import json,sqlite3

     ligne = []
     personal_nom = []
     tout = []

     conn = sqlite3.connect('database.db')
     cur = conn.cursor()
     cur.execute("""
     CREATE TABLE IF NOT EXISTS OPENLIBRARY3(
     id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
     nom TEXT,
     personal_name TEXT
     )
     """)
     conn.commit()

     with open('openlibrary.json') as file:
     for i in range(98):
        line = file.readline()
        if "bio" in line:
            line.replace("\'", "’")
            continue
        content_json = json.loads(line)
        if not "name" in line:
           #print('NULL')
           ligne.append("NULL")
           continue
        try:
            #print(content_json['name'])
            ligne.append(content_json['name'])
        except IndexError:
            print
        if not "personal_name" in line:
            # print('NULL')
            personal_nom.append("NULL")
            continue
        try:
            # print(content_json['name'])
            personal_nom.append(content_json['personal_name'])
        except IndexError:
            print


      #print(ligne)
      #print(personal_nom)


      #for i in ligne:



      new_list=[]
      #for y in range(0,len(ligne)):
      #    list.append(("("+ligne[(y)]+")"))

      #for element in ligne:
      #    new_list.append(tuple(element))

     #print(new_list)

     resultat = []
     for name in zip(ligne):
       resultat.append((name))
     #print(resultat)


     print(tout)


     cur.executemany("""
     INSERT INTO OPENLIBRARY3(nom) VALUES(?)""", resultat)
     #cur.executemany("""
     #INSERT INTO OPENLIBRARY3(personal_name) VALUES(?)""", personal_nom)

     valeur = []

    req = "select * from OPENLIBRARY3"
    result = cur.execute(req)
    print(type(result))
    for row in result:
       valeur.append(row[1])

    print(valeur)
    #for j in range(len(ligne)):
    #    content = ligne[j]
    #    content_json = json.loads(content)
    #    print(content_json['name'])

Спасибо, выслушайте меня, и если у вас есть вопросы, я здесь !!

Ответы [ 2 ]

1 голос
/ 09 февраля 2020

Вам нужен RegEx, чтобы исправить ваши грязные данные. Например, для поля «био» необходимо сопоставить имя «био» и его значение, которое содержит поле «тип» и поле «значение». Затем вы делаете то же самое с полем «значение»: вы можете исправить кавычки.

Вот один из способов сделать это:

import re
import json
import pprint


bio_regex = re.compile(
    r"""
("bio":\s*{)   # bio field start
(.*?)          # content
(},)           # bio field end
(?=\s*(?:"\w+"|}))  # followed by another one or the json end
""",
    flags=re.VERBOSE | re.DOTALL)

value_regex = re.compile(
    r"""
("value":\s*")   # value field start
(.*?)            # content
("\s*\Z)         # value field end + end of string
""",
    flags=re.VERBOSE | re.DOTALL)


def normalize_value(mo):
    start, content, end = mo.group(1, 2, 3)
    content = content.replace('"', '\\"')
    return start + content + end


def normalize_bio(mo):
    start, content, end = mo.group(1, 2, 3)
    content = value_regex.sub(normalize_value, content)
    return start + content + end

messy_json = """
{ 
  "bio":{ 
    "type":"/type/text",
    "value":"> "Eversley, William Pinder, B.C.L. Queen's Coll., Oxon, M.A., a member of the South-eastern circuit, reporter for Law Times in Queen's Bench division, a student of the Inner Temple 14 April, 1874 (then aged 23), called to the bar 25 April, 1877 (eldest son of William Eversley, Esq., of London); born u2060, 1851. rn> rn> 7, King's Bench Walk, Temple, E.C." rn> ...[in Foster's Men at the Bar][1]rnrnrn rnrn[1]: https://en.wikisource.org/wiki/Men-at-the-Bar/Eversley,_William_Pinder "Men at the Bar""
  },
  "name":"William Pinder Eversley",
  "created":{ 
    "type":"/type/datetime",
    "value":"2008-04-01T03:28:50.625462"
  },
  "death_date":"1918",
  "photos":[ 
    6897255,
    6897254
  ],
  "last_modified":{ 
    "type":"/type/datetime",
    "value":"2018-07-31T15:39:07.982159"
  },
  "latest_revision":6,
  "key":"/authors/OL1003081A",
  "birth_date":"1851",
  "personal_name":"William Pinder Eversley",
  "type":{ 
    "key":"/type/author"
  },
  "revision":6
}"""


result = bio_regex.sub(normalize_bio, messy_json)
obj = json.loads(result)

Вот результат:


{'bio': {'type': '/type/text',
         'value': '> "Eversley, William Pinder, B.C.L. Queen\'s Coll., Oxon, M.A., a member of the '
                  "South-eastern circuit, reporter for Law Times in Queen's Bench division, a student of "
                  'the Inner Temple 14 April, 1874 (then aged 23), called to the bar 25 April, 1877 (eldest '
                  "son of William Eversley, Esq., of London); born u2060, 1851. rn> rn> 7, King's Bench "
                  'Walk, Temple, E.C." rn> ...[in Foster\'s Men at the Bar][1]rnrnrn rnrn[1]: '
                  'https://en.wikisource.org/wiki/Men-at-the-Bar/Eversley,_William_Pinder "Men at the Bar"'},
 'birth_date': '1851',
 'created': {'type': '/type/datetime', 'value': '2008-04-01T03:28:50.625462'},
 'death_date': '1918',
 'key': '/authors/OL1003081A',
 'last_modified': {'type': '/type/datetime', 'value': '2018-07-31T15:39:07.982159'},
 'latest_revision': 6,
 'name': 'William Pinder Eversley',
 'personal_name': 'William Pinder Eversley',
 'photos': [6897255, 6897254],
 'revision': 6,
 'type': {'key': '/type/author'}}

Вы можете использовать это, чтобы исправить вашу программу.

0 голосов
/ 17 февраля 2020

Спасибо за ответ

Итак, я взял ваш код с прошлого раза, и он отлично работает, но проблема в том, что я не могу поместить все свои строки "био" в файл, чтобы обработать их 1 на 1 Мне нужен скрипт для обработки каждой строки и правильного их написания. Но хороший новый! Это всегда одна и та же проблема со строкой «био», поэтому я попытался поставить al oop, чтобы обработать всю мою строку био моего файла базы данных

with open('openlibrarytest.json') as file:
for line in range(10000):
    try:
        line = file.readline()
        content_json = json.loads(line)
    except JSONDecodeError:
        continue
    if not "bio\"" in line:
        #bio.append("NULL")
        continue
    try:
        # print(content_json['name'])
        bio.append(line)

    except IndexError:
       print

print(bio)

Как видите, я пытаюсь восстановить все линии bio в файле с 100000 строк, который имеет более 100 строк «bio», я попытался взять ваш код и сделать al oop для всех строк bio, но это не сработало,

Я бы как знать, как я могу это сделать, пожалуйста, чтобы поставить его на все линии

Заранее спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...