97

I am trying to migrate from sqlalchemy(SQlite) to using mongodb. I would like schema vertification. I amm looking at mongokit, but I want something which is similar to mappers, so that it would save from the object's property, and not a dict.

i would like a mapper so that i can use existing objects without modifying them.

5
  • 1
    Precisely, it should be called "DRM" (Document-Resource-Mapping) Commented Jan 26, 2012 at 21:27
  • This should help you answer your query docs.mongodb.org/ecosystem/drivers/php-libraries Commented Sep 29, 2013 at 4:12
  • There's a library called mongolia that let's you interact with mongo objects via attributes or dictionary access and has schema verification that you can enable: github.com/zagaran/mongolia Commented Mar 11, 2014 at 0:45
  • @zsong Relational and Document... Shouldnt be called Object Relational and Object Document? Commented Feb 26, 2015 at 11:05
  • this may be helpful: pythonhosted.org/Flask-MongoAlchemy Commented May 2, 2019 at 17:52

4 Answers 4

76

Another option is MongoEngine. The ORM for MongoEngine is very similar to the ORM used by Django.

Example (from the tutorial):

class Post(Document):
    title = StringField(max_length=120, required=True)
    author = ReferenceField(User)

class TextPost(Post):
    content = StringField()

class ImagePost(Post):
    image_path = StringField()

class LinkPost(Post):
    link_url = StringField()
Sign up to request clarification or add additional context in comments.

10 Comments

AFAIK. You can't add properties on the fly to mongoengine's Document. Which kind of takes some fun away from mongodb.
You can use the DictField to add any kind of totally schemaless data if you need to.
Mongoengine has some serious performance issues. If you want to use it in production, it will only work if you have a very simple, lightweight schema.
For those looking for a more comprehensive overview of MongoDB ORMs available for Python, the PyMongo "Tools" page lists quite a few of them, and is regularly maintained: api.mongodb.com/python/current/tools.html
The PyMongo tools page has moved: pymongo.readthedocs.io/en/stable/tools.html
|
43

Not being satisfied with either MongoKit or MongoEngine, I decided to write my own object-oriented interface for Python.

I delegated all queries directly to pymongo, so the query syntax there is the same. Mostly, it's just an object-wrapper around the results, with some other helpers like database connection pooling, DBRef support, and other convenience methods to make your life easier.

It's called Minimongo and it's available from github. Happy hacking!

Example:

from minimongo import Model, MongoCollection 

class MyObject(Model): 
    model = MongoCollection(database='test', collection='my_collection')

m = MyObject()
m.x = 1
m.field = 'value'
m.other = {'list': True}
m.save()

x = MyObject({'x': 1, 'y': 2}).save()

objs = MyObject.find({'x': 1})
for o in objs: 
    print o

2 Comments

This is super useful and simple, I just wanted something so that I am not stuck creating dictionaries, nothing else.
This is really nice. Too bad its not maintained anymore :(
31

You want MongoKit. It is one layer of abstraction higher than PyMongo. Not sure if you're using Django, but there's also django-mongokit integration.

Example from this blog post. Note that instances of Computer can then reference make/model directly once the structure is defined ( e.g. atari.make, c64.model, ... ). No need for dictionaries:

import datetime 
from mongokit import Document

class Computer(Document):

    structure = { 
      'make': unicode, 
      'model': unicode, 
      'purchase_date': datetime.datetime, 
      'cpu_ghz': float, 
    }

    validators = { 
      'cpu_ghz': lambda x: x > 0, 
      'make': lambda x: x.strip(), 
    }

    default_values = { 
      'purchase_date': datetime.datetime.utcnow, 
    }

    use_dot_notation = True

    indexes = [ 
      {'fields': ['make']}, 
    ]

5 Comments

is there a way to do this without modifying existing business logic objects? in sqlalchemy, you can use mappers.
more surgical change. keeps your dependency graph clean. makes sense, though I don't see a way to do this directly. Maybe something strange like class MongoComputer(Computer,Document) or with some form of mix in? Interesting...
its clean in sqlalchemy, thus the question, thans
No code changes in mongokit since 2015 and no release since 2014. damn, I don't get this python world :( .
MongoKit is dead
17

I know I'm really late to this question, but I'm the author of Ming http://merciless.sourceforge.net, a SQLAlchemy-inspired MongoDB validation and ORM engine. It's what we use at SourceForge, and there's a reasonable presentation available at http://www.slideshare.net/rick446/rapid-and-scalable-development-with-mongodb-pymongo-and-ming as well as a case study on migrating from SQLAlchemy to Ming http://www.slideshare.net/__amol__/from-sqlalchemy-to-ming-with-turbogears2. Here's an example of the ORM layer in Ming (from the tutorial):

class WikiPage(MappedClass):

    class __mongometa__:
        session = session
        name = 'wiki_page'

    _id = FieldProperty(schema.ObjectId)
    title = FieldProperty(str)
    text = FieldProperty(str)
    comments=RelationProperty('WikiComment')

Queries use the standard MongoDB query syntax (not Django ORM's magic keyword arguments):

WikiComment.query.find(dict(page_id=wp._id))

2 Comments

Ming seems for us the way to go. It has both the flexibility and the schema-ish concepts we need. When we need power we drop down to pymongo.
I am new to mongo and python. Is there a tutorial where I can refer to for creating Models like django's model.py and create migration scripts using Ming.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.