Как сохранить порядок dict в PyMongo [duplicate]

У меня была следующая конфигурация, приводящая к той же ошибке при запросе ответов с сервера.

Серверная сторона: SparkJava - > предоставляет клиентскую часть REST-API: ExtJs6 -> обеспечивает рендеринг браузера

На стороне сервера мне пришлось добавить это к ответу:

Spark.get("/someRestCallToSpark", (req, res) -> {
    res.header("Access-Control-Allow-Origin", "*"); //important, otherwise its not working 
    return "some text";
 });

На стороне клиента мне пришлось добавить к запросу:

Ext.Ajax.request({
    url: "http://localhost:4567/someRestCallToSpark",
    useDefaultXhrHeader: false, //important, otherwise its not working
    success: function(response, opts) {console.log("success")},
    failure: function(response, opts) {console.log("failure")}
});

14
задан fat fantasma 11 April 2014 в 00:54
поделиться

4 ответа

Вы можете использовать bson.son.SON или OrderedDict для сохранения упорядоченного dict.

И получить данные с помощью опции as_class=OrderedDict.

Вот пример:

from collections import OrderedDict
from pymongo import MongoClient
import bson

client = MongoClient()
sample_db = client['sample']
test_col = sample_db['test']

test_col.drop()

data = OrderedDict([("one", 1), ("two", 2), ("three", 3), ("four", 4)])
test_col.insert(data)
print(list(test_col.find({}, {'_id': 0}, as_class=OrderedDict)))

test_col.drop()

data = bson.son.SON([("one", 1), ("two", 2), ("three", 3), ("four", 4)])
test_col.insert(data)
print(list(test_col.find({}, {'_id': 0}, as_class=OrderedDict)))

Выход:

[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])]
[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])]
12
ответ дан Omid Raha 25 August 2018 в 13:46
поделиться

Это решение выше для старых версий MongoDB и драйвера pymongo, но оно больше не работает с pymongo3 и MongoDB3 +. Теперь вам нужно добавить document_class=OrderedDict в конструктор MongoClient. Изменение указанного ответа для совместимости pymongo3.

from collections import OrderedDict
from pymongo import MongoClient
import bson

client = MongoClient(document_class=OrderedDict)
sample_db = client['sample']
test_col = sample_db['test']

test_col.drop()

data = OrderedDict([("one", 1), ("two", 2), ("three", 3), ("four", 4)])
test_col.insert(data)
print(list(test_col.find({}, {'_id': 0})))

test_col.drop()

data = bson.son.SON([("one", 1), ("two", 2), ("three", 3), ("four", 4)])
test_col.insert(data)
print(list(test_col.find({}, {'_id': 0})))

Выход:

[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])]
[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])]
14
ответ дан Alan Viars 25 August 2018 в 13:46
поделиться

Стандартная find () в PyMongo не вернет объект, поля которого находятся в том же порядке, что и этот объект, если вы извлекли его через оболочку mongo.

Это связано с тем, что возвращаемый по умолчанию тип Dict и порядок не определены.

Вы можете использовать SON как предложено. Вот как я это сделал. Теперь порядок поля будет соблюден.

Это для pymongo == 3.4.0

from bson.codec_options import CodecOptions
from bson.son import SON

opts = CodecOptions(document_class=SON)
collection_son = mongo.db.collection.with_options(codec_options=opts)

collection_son.find_one({"imsid": '12345'})
3
ответ дан jowan sebastian 25 August 2018 в 13:46
поделиться

В PyMongo v3.2 insert() устарела, и в этом примере она должна быть заменена на insert_one(). Обновленный код ниже:

from collections import OrderedDict
from pymongo import MongoClient
import bson

client = MongoClient(document_class=OrderedDict)
sample_db = client['sample']
test_col = sample_db['test']

test_col.drop()

data = OrderedDict([("one", 1), ("two", 2), ("three", 3), ("four", 4)])
test_col.insert_one(data)
print(list(test_col.find({}, {'_id': 0})))

test_col.drop()

data = bson.son.SON([("one", 1), ("two", 2), ("three", 3), ("four", 4)])
test_col.insert_one(data)
print(list(test_col.find({}, {'_id': 0})))

Выход:

[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])]
[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])]
2
ответ дан Richard Erickson 25 August 2018 в 13:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: