Skip to content

Commit ca1fcdc

Browse files
authored
Merge pull request #24 from better/refs
Support more generic $refs
2 parents 4414877 + dc20c0f commit ca1fcdc

3 files changed

Lines changed: 48 additions & 11 deletions

File tree

jsonschema2db.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,16 @@ def _traverse(self, schema, tree, path=tuple(), table='root', parent=None, comme
109109
definition = None
110110
new_json_path = json_path
111111
while '$ref' in tree:
112-
p = tree['$ref'].lstrip('#').lstrip('/').split('/')
113-
# TODO: I actually don't think it's required JSON schema that all definitions have to go under #/definitions
114-
if len(p) != 2 and p[0] != 'definitions':
115-
warnings.warn('%s.%s: Broken reference: %s' % (table, self._column_name(path), tree['$ref']))
116-
return
117-
_, definition = p
118-
if definition not in schema['definitions']:
119-
warnings.warn('%s.%s: Broken definition: %s' % (table, self._column_name(path), definition))
120-
return
121-
tree = schema['definitions'][definition]
122-
new_json_path = ('#', 'definitions', definition)
112+
ref = tree['$ref']
113+
p = ref.lstrip('#').lstrip('/').split('/')
114+
tree = schema
115+
for elem in p:
116+
if elem not in tree:
117+
warnings.warn('%s.%s: Broken definition: %s' % (table, self._column_name(path), ref))
118+
return
119+
tree = tree[elem]
120+
new_json_path = ('#',) + tuple(p)
121+
definition = p[-1] # TODO(erikbern): we should just make this a boolean variable
123122

124123
special_keys = set(tree.keys()).intersection(['oneOf', 'allOf', 'anyOf'])
125124
if special_keys:
@@ -137,6 +136,7 @@ def _traverse(self, schema, tree, path=tuple(), table='root', parent=None, comme
137136
res = {}
138137
warnings.warn('%s.%s: Type info missing' % (table, self._column_name(path)))
139138
elif tree['type'] == 'object':
139+
print('object:', tree)
140140
res = {}
141141
if 'patternProperties' in tree:
142142
# Always create a new table for the pattern properties

test/test.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,12 @@ def test_time_types():
109109
[(1, datetime.date(2018, 7, 8)), (2, datetime.date(2013, 3, 2))]
110110
assert list((id, ts.isoformat()) for id, ts in query(con, 'select id, ts from root')) == \
111111
[(1, '2018-02-03T12:45:56+00:00'), (2, '2017-02-03T01:23:45+00:00')]
112+
113+
114+
def test_refs():
115+
schema = json.load(open('test/test_refs.json'))
116+
translator = JSONSchemaToPostgres(schema, debug=True)
117+
118+
con = psycopg2.connect('host=localhost dbname=jsonschema2db-test')
119+
translator.create_tables(con)
120+
assert list(query(con, 'select col from c')) == [] # Just make sure table exists

test/test_refs.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"$schema": "http://json-schema.org/schema#",
3+
"type": "object",
4+
"a": {
5+
"b": {
6+
"c": {
7+
"type": "object",
8+
"properties": {
9+
"col": {
10+
"type": "string"
11+
}
12+
}
13+
}
14+
}
15+
},
16+
"x": {
17+
"y": {
18+
"z": {
19+
"$ref": "#/a/b/c"
20+
}
21+
}
22+
},
23+
"properties": {
24+
"banana": {
25+
"$ref": "#/x/y/z"
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)