2016-04-11 2 views
2

В Python у меня есть список словарей. Список называется members, и каждый член имеет уникальный id. Например, список может выглядеть следующим образом:Обновление базы данных из списка словарей

members = [{'id':1, 'val1':10, 'val2':11}, 
      {'id':2, 'val1':2, 'val2':34}, 
      {'id':3, 'val1':350, 'val2':9}] 

Я хочу обновить свою коллекцию со списком членов, обновления и вставки новых записей по мере необходимости.

Нужно ли мне проходить через элементы, или есть более быстрый способ?

Вот моя попытка, которая, кажется, делать то, что я хочу, но занимает некоторое время:

for m in members: 
    collection.update_one({'id':m['id']}, {'$set': m)}, upsert = True) 

Обратите внимание, что это требует обновлений каждой записи дб с другим значением, а именно тот, который соответствует ее id.

+0

Доступ к ключам осуществляется через m ['id']. Выполнение m.id доступа к атрибуту «id», который не существует. – keksnicoh

+0

@keksnicoh yep, fixed question – Hatshepsut

ответ

0

Используйте update_many, если у вас одинаковые значения.

Но если у вас разные значения, вы не можете обновить сразу два документа с помощью запроса MongoDB. Вам всегда придется делать это в двух запросах. Вы можете, конечно, установить значение поля в одно и то же значение или увеличить его с тем же номером, но вы не можете сделать два отдельных обновления в MongoDB с тем же запросом.

+0

Я не уверен, как применить это к моей ситуации, где мне нужно сопоставить не только «x: 1», но и каждый _different_ 'id', и обновить соответствующую запись db. – Hatshepsut

+0

@Hatshepsut, используйте $ или для указания другого идентификатора – JRazor

+0

Я добавил пример такого списка, который у меня есть. Если возможно, можете ли вы дать код, показывающий, как обновить db с помощью 'val1' и' val2', соответствующих каждому уникальному 'id'? – Hatshepsut

0

С современной PyMongo вы можете использовать .bulk_write() с операцией записи ReplaceOne насыпной, в вашем конкретном случае, или в противном случае соответствующей операции

from pymongo import MongoClient 
from pymongo import ReplaceOne 

client = MongoClient() 

db = client.test 

members = [ 
    { 'id': 1, 'val1': 10, 'val2': 11 }, 
    { 'id': 2, 'val1': 2, 'val2': 34 }, 
    { 'id': 3, 'val1': 350, 'val2': 9 } 
] 

db.testcol.bulk_write([ 
    ReplaceOne(
    { "id": m['id'] }, 
    m, 
    upsert=True 
) 
    for m in members 
]) 

В идеале вы бы не обрабатывать из «списка» источника и вместо чтения в некотором внешнем «потоке», чтобы сохранить требования к памяти. Подобным же образом, вы бы просто построить вверх список операций аргумента для сказать 1000 операции и последующих вызов .bulk_write() на сервер для каждого только 1000.

Но всего дело в том, что с .bulk_write() вы отправляете «партию» все в один раз и только с одним ответом, а не как отдельные запросы с отдельными ответами, что создает накладные расходы и требует времени.

Кроме того, использование этого метода API фактически использует "Bulk API" под серверами, но ухудшает работу с индивидуальными вызовами, когда версия сервера не поддерживает методы «Массовые».

Смежные вопросы