Commits

Andy Mikhailenko committed fd43d61

Update documentation: add comparison to MongoEngine

Comments (0)

Files changed (3)

 **No.**
 Monk comes with a MongoDB extension but since v.0.6 the dependency is optional.
 
+Does Monk support DBRefs and other MongoDB features?
+----------------------------------------------------
+
+**Yes.**
+However, there's room for improvement.  Feel free to submit your use cases.
+
 Is Monk stable enough?
 ----------------------
 
 inevitable competition between Monk and these projects; Monk aims to be better
 and the list shows how it is better.  I mean, what's the point of creating
 a project if not to make a solution that would incorporate the strong points
-and address the weaknesses of its predecessors?  So, here we go.
+and address the weaknesses of its predecessors?  Oh well.
+
+.. note:: Spotted an error?
+
+   Please excuse me for possible false assumptions about the projects being
+   described; if you find an error, please don't hesitate to poke me via e-mail
+   or the issue tracker (as this would be a proper documentation issue).
 
 Schema Definition
 -----------------
 
+**Monk**
+  See :mod:`monk.schema`.
+
 MongoKit_
   Simple and pythonic, very similar to Monk (actually, Monk's "natural" DSL was
   inspired by that of MongoKit).  However, everything is tightly bound to
   MongoDB (not to mention the lacking possibility to work with plain data
   without ODMs); the required flag, default values and custom validators are
-  defined on the root level, duplicating the structure in each case. Example::
+  defined on the root level, duplicating the structure in each case.
 
-      # Monk
-
-      spec = {
-          'foo': 5,
-          'bar': optional(str),
-          'baz': {
-              'quux': 'flux'
-          }
-      }
-
-      # MongoKit
+  MongoKit example::
 
       class Spec(Document):
           structure = {
           }
           required = ['foo', 'baz.quux']
 
+      Spec(**data).validate()
+
+  Semantically equivalent schema in Monk (without classes)::
+
+      spec = {
+          'foo': 5,
+          'bar': optional(str),
+          'baz': {
+              'quux': 'flux'
+          }
+      }
+
+      validate(spec, data)
+
   Very similar support (and notation) for nested lists and dicts; also supports
   nested tuples.
 
+MongoEngine_
+  Very verbose Django-like syntax, traditional for ORMs.
+
+  MongoEngine example::
+
+      class User(Document):
+          name = StringField(required=True)
+
+      class Comment(EmbeddedDocument):
+          author = ReferenceField(User, required=True)
+          content = StringField(required=True)
+          added = DateTimeField(required=True, default=datetime.datetime.utcnow)
+
+      class Post(Document):
+          title = StringField(required=True)
+          author = ReferenceField(User)
+          tags = ListField(StringField())
+          comments = ListField(EmbeddedDocumentField(Comment))
+
+  Semantically equivalent schema in Monk (without classes)::
+
+      user = {'name': str}
+
+      comment = {
+          'author': ObjectId,   # see monk.modeling; still needs work
+          'content': str,
+          'added': datetime.datetime.utcnow,
+      }
+
+      post = {
+          'title': str,
+          'author': ObjectId,
+          'tag': [ optional(str) ],
+          'comments': [ optional(comment) ]
+      }
+
+  MongoEngine allows things like ``StringField(max_length=30)`` (traditional
+  ORM stuff, barely needed in ODMs) which Monk doesn't support out of the box
+  though it's easily achievable with custom validators.  The `FooField` layer
+  can be added on top of the normal Monk syntax if needed.
+
+  MongoEngine is tightly bound to MongoDB and provides many database-specific
+  features which are not present in Monk (e.g. defining deletion policy of
+  referred documents).
+
 Validation
 ----------
 
+**Monk**
+  See :mod:`monk.validation`.
+
 MongoKit_
   Type validation (extensible with custom types).  All validators beyond types
   belong in a separate dictionary which mostly duplicates the schema dictionary.
   the normal and a custom validation functions one after another (or overload
   the method in a similar way if using modeling).
 
+MongoEngine_
+  Validation is integrated into `FooField` classes and triggered on save.
+  Only very basic validators (required, unique, choices) are tunable. Custom
+  validation implies custom field classes.  For each field.  Ouch.
+
 Manipulation
 ------------
 
+**Monk**
+  See :mod:`monk.manipulation`.
+
 MongoKit_
   Data manipulation mostly embraces conversion between Python types and MongoDB
   internal representation (via PyMongo).  This can be tuned with "Custom Types"
 
   It is unknown whether the list of default values supports callables.
 
+MongoEngine_
+  Mostly embraces conversion between Python types and MongoDB.  This is always
+  implemented by `FooField` classes that handle both manipulation and
+  validation.
+
+  Supports callable defaults.
+
 Modeling
 --------
 
+**Monk**
+  See :mod:`monk.modeling`.
+
+  :lightweight schema:
+    Yes.  The schema is not bound to any kind of storage or form.
+    It can be — just add another layer on top.
+
+  :reusable parts:
+    Yes.  The Document class can be used right away, subclassed or be built
+    anew from the components that were designed to be reusable.
+
+    This makes Monk a good building block for custom ODMs.
+
+  :dot-expanded dictionary behaviour:
+    Yes.
+
+  :polymorphism (document inheritance):
+    Not yet.
+
 MongoKit_
-  The Document class is bound to a MongoDB collection.  Supports dot-expanded
-  dictionary behaviour (like Monk).  Supports polymorphism (Monk doesn't).
-  The underlying functions are not intended to be used separately (in Monk this
-  was one of the main design goals).
+  :lightweight schema:
+    No.  The Document class is bound to a MongoDB collection.
+
+  :reusable parts:
+    No.  The underlying functions are not intended to be used separately.
+
+  :dot-expanded dictionary behaviour:
+    Yes.
+
+  :polymorphism (document inheritance):
+    Yes.
+
+MongoEngine_
+  :lightweight schema:
+    No.  The Document class is bound to a MongoDB collection.
+
+  :reusable parts:
+    No.  The underlying functions are not intended to be used separately.
+
+  :dot-expanded object behaviour:
+    Yes.
+
+  :polymorphism (document inheritance):
+    Yes.
 
 MongoDB extension
 -----------------
 
+**Monk**
+  See :mod:`monk.mongo`.
+
 MongoKit_
   Tightly bound to MongoDB on all levels.  The document class is bound to
   a collection (which I found problematic in the past but generally this may be
   PyMongo so the basic functionality is exactly the same.  The choice depends
   on given project's use cases.
 
+MongoEngine_
+  Seems to be on par with MongoKit.
+
 .. _MongoKit: http://namlook.github.io/mongokit/
+.. _MongoEngine: https://mongoengine-odm.readthedocs.org
 

monk/validation.py

     Always returns ``None``.
 
     :rule:
-        a :class:`~monk.schema.Rule` instance.
+        a :class:`~monk.schema.Rule` instance or any other value digestible
+        by :func:`canonize`.
     :value:
         any value including complex structures.