Использование: Python 3.7.3, SQLAlchemy 1.3.13 с sqlite.
Я пытаюсь добавить данные из следующей структуры JSON в поле JSON в моей базе данных.
Это то, чего я добиваюсь, но я изо всех сил стараюсь добавить: «Второе сообщение», «Третье сообщение» и т. Д. c ...
data = {
"title":'some title',
"status": "some status",
"logs": [
[mytimestamp, "First message"],
[mytimestamp, "Second message"],
[mytimestamp, "Third message"]
]
}
Вставка вышеуказанной структуры данных в базу данных работает нормально. Как это:
tablename = Tablename(someint=1, data=data)
try:
db.session.add(tablename)
db.session.commit() <--- success every time
except:
print('Error creating record')
Обновление и изменение элементов верхнего уровня (таких как «заголовок», «статус») я могу сделать без проблем. Я даже могу добавить дополнительные.
tablename = Tablename.query.get(id)
try:
tablename.data = newdata <--- newdata is where the problem is
tablename.someint = 2 <--- this always updates without problem
db.session.commit()
except:
print('Error updating record')
Но когда дело доходит до добавления дополнительных элементов массива в «журналы», это то, где это становится совершенно странным ... запись базы данных будет обновляться, но за исключением моего JSON поле, но оно также не выдает исключение, оно просто обновляет другие столбцы базы данных, но игнорирует мое поле JSON.
Я пробовал различные способы добавления (), обновления (), даже это работает tablename.data = {**olddata, **newdata}
но ТОЛЬКО для предметов верхнего уровня. Как только я пытаюсь манипулировать данными ВНУТРИ "журналов", тогда это:
Либо: ошибки, потому что я пытаюсь манипулировать данными неправильно (достаточно справедливо)
Или: молча игнорирует тот факт, что я обновляю столбец данных ДАЖЕ, если при печати (newdata) и выходном значении, которое я хочу поместить в БД, я МОГУ ВИДЕТЬ, что это правильно .. Но БД просто игнорирует это!
Чего я не понимаю, так это того, что data
с радостью будет вставлен в БД, и я смогу найти способы обновить объект (даже если это некрасиво, на данном этапе я просто хочу, чтобы он работал!), который я получаю из базы данных с помощью запроса, но я не понимаю, почему я могу напечатать полученный объект в CLI, и он выглядит хорошо, но БД просто молча игнорирует это (someint
всегда обновляется во время тихих сбоев)! По крайней мере, выдать ошибку, если она не действительна?
У кого-нибудь есть идеи? Как бы вы добавили строки в «журналы»?
--- ВАЖНОЕ ОБНОВЛЕНИЕ ---
Поскольку результаты, которые я получил вчера, не имели для меня никакого логического смысла, я отбросил тему и вернулись сегодня с свободными sh глазами. Это то, что я сделал и нашел до сих пор, мои выводы не радуют , но по крайней мере у меня есть решение, которое теперь, кажется, работает: используйте поле VARCHAR вместо поля JSON в база данных.
Вот как я пришел к выводу:
Я добавил дополнительный столбец в таблицу базы данных, поэтому теперь у меня есть:
data1 -> type: JSON
data2 -> type: VARCHAR
Это мой тест код:
# Get the data
tablename = Tablename.query.get(id)
d1 = tablename.data1 # from JSON field
d2 = json.loads(tablename.data2) # from VARCHAR field
# Append a log message
logs = d1['logs'] # <--- See note 1 below
# logs = d2['logs'] # <--- See note 2 below
logs.append([mytimestamp, message])
newlogs = {'logs': logs}
# Update database record with new data
tablename.data1 = {**d1, **newlogs} # Into JSON field
tablename.data2 = json.dumps({**d2, **newlogs}) # Into VARCHAR field
db.session.commit()
Примечание 1. Если я использую d1
в качестве источника (то есть: из столбца JSON), тогда поле data1
не обновляется с новым сообщением, но data2
поле делает!
Примечание 2: Если я использую d2
в качестве источника (то есть: из столбца VARCHAR), тогда оба поля data1
и data2
будут успешно обновлены новым сообщением.