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
orpybson
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | c3644dbffd9ad9bcf8da08545580d1659a3ebe1beb67d54bbd58c12987836dac |
|
MD5 | 010fcd5db126af7b5c1ef25b5f07054d |
|
BLAKE2b-256 | 8e85392fbd77c25f1f375255340424158d2ae7ef509a01e67d3dd98e057712b1 |
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 363f396f2862643853814f42257547e32581194fe997185ae325633a222f6651 |
|
MD5 | 9b95227c787abc1314629d72f887c0fd |
|
BLAKE2b-256 | 9d121742c76b1b448e8600eb7e2ee7d8406d37bd1cab320657aa5d891996c50c |