Skip to main content

Schema validator for MongoDB's JSON Schema variant

Project description

mongo-schema

Extended JSON Schema validator for MongoDB's JSON Schema variant.

Introduction

Since MongoDB 3.6, MongoDB has supported server-side validation of documents inserted into a collection by attaching a schema to that collection in an extended version of JSON Schema. It is almost the same JSON Schema draft 4, but with a few custom extensions, as well as omissions, that are of course not handled by existing JSON Schema validators such as jsonschema for Python.

This would not be a problem since we can test our schemas directly on our MongoDB server. However, anyone who's used this feature has probably found that schema validation error responses from the server can be...a little less than helpful[^1]:

> db.createCollection("test", {"validator": {"$jsonSchema": {"properties": {"count": {"bsonType": "int"}}}}})
{ "ok" : 1 }
> db.test.insert({"count": "abc"})
WriteResult({
	"nInserted" : 0,
	"writeError" : {
		"code" : 121,
		"errmsg" : "Document failed validation"
	}
})

In this case we can clearly see that the value of "count" is not an int as required by the schema. But for even moderately-sized documents with more than a handful of schema validation rules, document validation errors can be extremely tricky to track down.

This module was created to help debug validation issues in applications using non-trivial schemas to validate their MongoDB documents. It extends the Draft4Validator of jsonschema to support the metaschema and validators used by MongoDB's JSON Schema variant, in particular with support for the bsonType validator.

[^1]: This has actually been fixed quite recently as of MongoDB 4.9.0.

Installation

Dependencies:

  • jsonschema
  • One of: pymongo or pybson

The mongo-schema package does not explicitly include a dependency for the bson package. Normally this package is installed as part of pymongo, but it is a somewhat heavy-weight dependency to add, and has a stand-alone version in the form of pybson. So it is recommended to install on or the other. Most users of this package will already be using pymongo as one of their dependencies:

$ pip install pymongo mongo-schema

or

$ pip install pybson mongo-schema

Note: Do not confuse this package with the mongoschema package on PyPI, which is unrelated.

Usage

Simply use mongo_schema.validate which has the same interface as jsonschema.validate. Here are some examples demonstrating bsonType validation:

>>> import mongo_schema
>>> mongo_schema.validate(123, {'bsonType': 'int'})
>>> mongo_schema.validate(123, {'bsonType': 'long'})
>>> mongo_schema.validate(2**65, {'bsonType': 'long'})
Traceback (most recent call last):
...
jsonschema.exceptions.ValidationError: 36893488147419103232 is not of type
'long'
>>> mongo_schema.validate(b'\x00\x11\x22', {'bsonType': 'binData'})
>>> from datetime import datetime
>>> mongo_schema.validate(datetime.now(), {'bsonType': 'date'})

Note that the schema itself is validated against a meta-schema which, like MongoDB, explicitly disallows certain properties such as $schema or $ref, as well as custom properties. These will result in validation errors on the schema itself:

>>> mongo_schema.validate({}, {'$ref': '#/definitions/myDef'})
Traceback (most recent call last):
...
jsonschema.exceptions.SchemaError: Additional properties are not allowed
('$ref' was unexpected)
...
>>> mongo_schema.validate({}, {'foo': 'bar'})
Traceback (most recent call last):
...
jsonschema.exceptions.SchemaError: Additional properties are not allowed
('foo' was unexpected)
...

You can also create a validator instance wrapping a specific schema using mongo_schema.MongoValidator:

>>> validator = mongo_schema.MongoValidator({'bsonType': 'objectId'})
>>> from bson import ObjectId
>>> validator.validate(ObjectId())

A typical use case for this package might be to add better error output when schema validation fails upon document insertion or update. For example:

document = {'a': 123}
try:
    my_db.my_collection.insert_one(document)
except pymongo.errors.WriteError as exc:
    if exc.code == 121:
        # Get the schema for the collection
        opts = my_db.my_collection.options()
        schema = opts.get('validator').get('$jsonSchema')
        # Raise a jsonschema.ValidationError with more details
        if schema is not None:
            mongo_schema.validate(document, schema)

    raise

Here exc.code == 121 is the MongoDB error code for DocumentValidationError, though as far as I can tell this is not made available anywhere by the pymongo driver.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mongo-schema-1.0.0.post0.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

mongo_schema-1.0.0.post0-py3-none-any.whl (7.1 kB view details)

Uploaded Python 3

File details

Details for the file mongo-schema-1.0.0.post0.tar.gz.

File metadata

  • Download URL: mongo-schema-1.0.0.post0.tar.gz
  • Upload date:
  • Size: 7.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.4

File hashes

Hashes for mongo-schema-1.0.0.post0.tar.gz
Algorithm Hash digest
SHA256 c3644dbffd9ad9bcf8da08545580d1659a3ebe1beb67d54bbd58c12987836dac
MD5 010fcd5db126af7b5c1ef25b5f07054d
BLAKE2b-256 8e85392fbd77c25f1f375255340424158d2ae7ef509a01e67d3dd98e057712b1

See more details on using hashes here.

File details

Details for the file mongo_schema-1.0.0.post0-py3-none-any.whl.

File metadata

  • Download URL: mongo_schema-1.0.0.post0-py3-none-any.whl
  • Upload date:
  • Size: 7.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.4

File hashes

Hashes for mongo_schema-1.0.0.post0-py3-none-any.whl
Algorithm Hash digest
SHA256 363f396f2862643853814f42257547e32581194fe997185ae325633a222f6651
MD5 9b95227c787abc1314629d72f887c0fd
BLAKE2b-256 9d121742c76b1b448e8600eb7e2ee7d8406d37bd1cab320657aa5d891996c50c

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page