Как использовать mongoengine в виде xxx[dbname?]

Используя pymongo, я могу подключиться к коллекции следующим образом:

conn = pymongo.MongoClient()
db = conn.example
collection = db.col

а затем я мог подключиться к базе данных с именем «example» и коллекции с именем «col».

И я мог бы также написать код, подобный удару:

dbname = 'example'
collectionName = 'col'
conn = pymongo.MongoClient()
db = conn[dbname]
connection = db[collectionName]

Эти два блока кода будут делать то же самое.

Теперь я использую mongoengine для подключения к MongoDB, и у меня есть база данных с collectionA, у меня также есть класс в файле с именем «model.py»:

class collectionA(Document):
    A=StringField()
    B= StringField()

поэтому я мог использовать только:

import model
x = model.collectionA.object()

для запроса данных.

так как у меня так много коллекций, поэтому я хотел бы использовать

model[collectionName].object() 

для запроса данных, но это вызывает исключение, кажется, что mongoengine не может поддерживать форму модели [xxx] для подключения коллекций.

Итак, есть ли способ решить эту проблему?


person Kingname    schedule 03.01.2016    source источник
comment
Вы пробовали import appname.model, где appname — это имя вашего приложения, а затем model['collectionName'].object()? Кроме того, какую ошибку вы получаете, вы использовали model[collectionName].object()   -  person Vaulstein    schedule 03.01.2016
comment
Имя приложения? Это скрипт на питоне.   -  person Kingname    schedule 03.01.2016
comment
Приняли это за приложение Django, потому что вы используете модель, как в Django. Какую ошибку вы получаете?   -  person Vaulstein    schedule 03.01.2016
comment
На самом деле это flask, а не Django. И ошибка: TypeError: объект 'module' не имеет атрибута 'getitem'   -  person Kingname    schedule 03.01.2016


Ответы (1)


Вы импортируете model.py как модуль. Синтаксис квадратных скобок — это «ярлык» для метода getitem объекта. Поскольку все в python является объектом, включая модули, вы получаете TypeError, потому что модули нет метода getitem.

То, чего вы пытаетесь достичь, можно сделать с помощью модуля inspect:

import inspect

import model

collections = dict(inspect.getmembers(model, inspect.isclass))

collections[collectionName].object() теперь будет работать.

FWIW это не кажется очень питоническим, и сила mongoengine заключается в том, что вы сопоставляете документы с четко определенными классами, и это, кажется, несколько запутывает это. Это позволяет очень легко вводить трудно обнаруживаемые ошибки, а также требует дополнительных нажатий клавиш, потому что каждый класс теперь упоминается как строка.

person Steve Rossiter    schedule 22.01.2016
comment
большое спасибо, попробую позже. Итак, по вашему опыту, какой более питонический способ в этой ситуации? - person Kingname; 23.01.2016
comment
То, как вы предлагаете в своем вопросе, мне подходит. Чтобы сохранить нажатия клавиш, вы можете использовать import models as db, а затем использовать db.CollectionA.objects (). Одним из основных преимуществ этого является то, что если вы используете IDE с проверкой кода, например PyCharm, вы получите параметры автозаполнения из вашего model.py. - person Steve Rossiter; 23.01.2016