Skip to main content

mapping jsonschema for sqlalchemy models

Project description

https://travis-ci.org/podhmo/alchemyjsonschema.svg

features

alchemyjsonschema is the library for converting sqlalchemys’s model to jsonschema.

  • using alchemyjsonschema as command
  • using alchemyjsonschema as library

as library

having three output styles.

  • NoForeignKeyWalker – ignore relationships
  • ForeignKeyWalker – expecting the information about relationship is foreign key
  • StructuralWalker – fullset output(expecting the information about relationship is full JSON data)

examples

dumping json with above three output styles.

target models are here. Group and User.

# -*- coding:utf-8 -*-
import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class Group(Base):
    """model for test"""
    __tablename__ = "Group"

    pk = sa.Column(sa.Integer, primary_key=True, doc="primary key")
    name = sa.Column(sa.String(255), default="", nullable=False)


class User(Base):
    __tablename__ = "User"

    pk = sa.Column(sa.Integer, primary_key=True, doc="primary key")
    name = sa.Column(sa.String(255), default="", nullable=True)
    group_id = sa.Column(sa.Integer, sa.ForeignKey(Group.pk), nullable=False)
    group = orm.relationship(Group, uselist=False, backref="users")

NoForeignKeyWalker

import pprint as pp
from alchemyjsonschema import SchemaFactory
from alchemyjsonschema import NoForeignKeyWalker

factory = SchemaFactory(NoForeignKeyWalker)
pp.pprint(factory(User))

"""
{'properties': {'name': {'maxLength': 255, 'type': 'string'},
                'pk': {'description': 'primary key', 'type': 'integer'}},
 'required': ['pk'],
 'title': 'User',
 'type': 'object'}
"""

ForeignKeyWalker

import pprint as pp
from alchemyjsonschema import SchemaFactory
from alchemyjsonschema import ForeignKeyWalker

factory = SchemaFactory(ForeignKeyWalker)
pp.pprint(factory(User))

"""
{'properties': {'group_id': {'type': 'integer'},
                'name': {'maxLength': 255, 'type': 'string'},
                'pk': {'description': 'primary key', 'type': 'integer'}},
 'required': ['pk', 'group_id'],
 'title': 'User',
 'type': 'object'}
"""

StructuralWalker

import pprint as pp
from alchemyjsonschema import SchemaFactory
from alchemyjsonschema import StructuralWalker

factory = SchemaFactory(StructuralWalker)
pp.pprint(factory(User))

"""
{'definitions': {'Group': {'properties': {'pk': {'description': 'primary key',
                                                 'type': 'integer'},
                                          'name': {'maxLength': 255,
                                                   'type': 'string'}},
                           'type': 'object'}},
 'properties': {'pk': {'description': 'primary key', 'type': 'integer'},
                'name': {'maxLength': 255, 'type': 'string'},
                'group': {'$ref': '#/definitions/Group'}},
 'required': ['pk'],
 'title': 'User',
 'type': 'object'}
"""

pp.pprint(factory(Group))

"""
{'definitions': {'User': {'properties': {'pk': {'description': 'primary key',
                                                'type': 'integer'},
                                         'name': {'maxLength': 255,
                                                  'type': 'string'}},
                          'type': 'object'}},
 'description': 'model for test',
 'properties': {'pk': {'description': 'primary key', 'type': 'integer'},
                'name': {'maxLength': 255, 'type': 'string'},
                'users': {'items': {'$ref': '#/definitions/User'},
                          'type': 'array'}},
 'required': ['pk', 'name'],
 'title': 'Group',
 'type': 'object'}
"""

as command

using alchemyjsonschema as command (the command name is also alchemyjsonschema).

help

$ alchemyjsonschema --help
usage: alchemyjsonschema [-h] [--walker {noforeignkey,foreignkey,structural}]
                         [--decision {default,fullset}] [--depth DEPTH]
                         [--out OUT]
                         target

positional arguments:
  target                the module or class to extract schemas from

optional arguments:
  -h, --help            show this help message and exit
  --walker {noforeignkey,foreignkey,structural}
  --decision {default,fullset}
  --depth DEPTH
  --out OUT             output to file

If above two model definitions (User,Group) are existed in alchemyjsonschema.tests.models .

Target is the class position or module position. for example,

  • class position – alchemyjsonschema.tests.models:User
  • module position – alchemyjsonschema.tests.models

example

Using StructuralWalker via command line (–walker structural). Of course, NoForeignKeyWalker is noforeignkey, and ForeignKeyWalker is foreignkey.

$ alchemyjsonschema --walker structural alchemyjsonschema.tests.models:Group

{
  "definitions": {
    "Group": {
      "properties": {
        "color": {
          "enum": [
            "red",
            "green",
            "yellow",
            "blue"
          ],
          "maxLength": 6,
          "type": "string"
        },
        "created_at": {
          "format": "date-time",
          "type": "string"
        },
        "name": {
          "maxLength": 255,
          "type": "string"
        },
        "pk": {
          "description": "primary key",
          "type": "integer"
        },
        "users": {
          "items": {
            "$ref": "#/definitions/User"
          },
          "type": "array"
        }
      },
      "required": [
        "pk"
      ],
      "title": "Group",
      "type": "object"
    },
    "User": {
      "properties": {
        "created_at": {
          "format": "date-time",
          "type": "string"
        },
        "name": {
          "maxLength": 255,
          "type": "string"
        },
        "pk": {
          "description": "primary key",
          "type": "integer"
        }
      },
      "required": [
        "pk"
      ],
      "type": "object"
    }
  }
}

Output is not same when using Walker-class, directly. This is handy output for something like a swagger(OpenAPI 2.0)’s tool.

appendix: what is –decision ?

what is –decision? (TODO: gentle description)

$ alchemyjsonschema --walker structural alchemyjsonschema.tests.models:User | jq . -S > /tmp/default.json
$ alchemyjsonschema --decision useforeignkey --walker structural alchemyjsonschema.tests.models:User | jq . -S > /tmp/useforeignkey.json
$ diff -u /tmp/default.json /tmp/useforeignkey.json
--- /tmp/default.json 2017-01-02 22:49:44.000000000 +0900
+++ /tmp/useforeignkey.json   2017-01-02 22:53:13.000000000 +0900
@@ -1,43 +1,14 @@
 {
   "definitions": {
-    "Group": {
-      "properties": {
-        "color": {
-          "enum": [
-            "red",
-            "green",
-            "yellow",
-            "blue"
-          ],
-          "maxLength": 6,
-          "type": "string"
-        },
-        "created_at": {
-          "format": "date-time",
-          "type": "string"
-        },
-        "name": {
-          "maxLength": 255,
-          "type": "string"
-        },
-        "pk": {
-          "description": "primary key",
-          "type": "integer"
-        }
-      },
-      "required": [
-        "pk"
-      ],
-      "type": "object"
-    },
     "User": {
       "properties": {
         "created_at": {
           "format": "date-time",
           "type": "string"
         },
-        "group": {
-          "$ref": "#/definitions/Group"
+        "group_id": {
+          "relation": "group",
+          "type": "integer"
         },
         "name": {
           "maxLength": 255,

0.4.2

  • fix bug calling command with module (not model class)

0.4.0

  • remove needless feature(#11)

0.3

  • swagger support(thanks of isysd)

Project details


Download files

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

Filename, size & hash SHA256 hash help File type Python version Upload date
alchemyjsonschema-0.5.0-py2.py3-none-any.whl (21.5 kB) Copy SHA256 hash SHA256 Wheel py2.py3 Jan 1, 2018
alchemyjsonschema-0.5.0.tar.gz (14.6 kB) Copy SHA256 hash SHA256 Source None Jan 1, 2018

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page