Skip to content

Commit 879712f

Browse files
committed
add base Piccolo & Encode ORM models
1 parent 39149f3 commit 879712f

10 files changed

+359
-34
lines changed

.pre-commit-config.yaml

-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
repos:
2-
- repo: https://github.com/asottile/seed-isort-config
3-
rev: v2.2.0
4-
hooks:
5-
- id: seed-isort-config
6-
- repo: https://github.com/pycqa/isort
7-
rev: 5.4.2
8-
hooks:
9-
- id: isort
102
- repo: https://github.com/ambv/black
113
rev: stable
124
hooks:

CHANGELOG.txt

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
**v0.6.0**
2+
Features:
3+
1. Added support for Encode ORM models https://github.com/encode/orm
4+
2. Added support for Piccolo ORM models https://piccolo-orm.readthedocs.io/en/latest/piccolo/schema/defining.html
5+
6+
17
**v0.5.1**
28
Fixes:
39
1. Sometimes multiple parents names in "parents" output was joined in one string - fixed.

README.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ Py-Models-Parser can parse & extract information from models & table definitions
99
- Sqlalchemy ORM (https://docs.sqlalchemy.org/en/14/orm/),
1010
- Gino ORM (https://python-gino.org/),
1111
- Tortoise ORM (https://tortoise-orm.readthedocs.io/en/latest/),
12+
- Encode ORM (https://github.com/encode/orm)
1213
- Django ORM Model (https://docs.djangoproject.com/en/3.2/topics/db/queries/),
1314
- Pydantic (https://pydantic-docs.helpmanual.io/),
1415
- Python Enum (https://docs.python.org/3/library/enum.html),
1516
- Pony ORM (https://ponyorm.org/),
17+
- Piccolo ORM models (https://piccolo-orm.readthedocs.io/en/latest/piccolo/schema/defining.html),
1618
- Pydal Tables definitions (http://www.web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#The-DAL-A-quick-tour),
1719
- Python Dataclasses (https://docs.python.org/3/library/dataclasses.html),
1820
- pure Python Classes (https://docs.python.org/3/tutorial/classes.html#class-objects)
@@ -171,12 +173,17 @@ For model from point 1 (above) library will produce the result:
171173

172174
## TODO: in next Release
173175

174-
1. Add more tests for supported models (and fix existed not covered cases): Django ORM, Pydantic, Enums, Dataclasses, SQLAlchemy Models, GinoORM models, TortoiseORM models, PonyORM, for lists
176+
1. Add more tests for supported models
175177
2. Add support for SQLAlchemy Core Tables
176-
3. Add support for Piccolo ORM models
177178

178179

179180
## Changelog
181+
**v0.6.0**
182+
Features:
183+
1. Added support for Encode ORM models https://github.com/encode/orm
184+
2. Added support for Piccolo ORM models https://piccolo-orm.readthedocs.io/en/latest/piccolo/schema/defining.html
185+
186+
180187
**v0.5.1**
181188
Fixes:
182189
1. Sometimes multiple parents names in "parents" output was joined in one string - fixed.

docs/README.rst

+10-2
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ Py-Models-Parser can parse & extract information from models & table definitions
2828
* Sqlalchemy ORM (https://docs.sqlalchemy.org/en/14/orm/),
2929
* Gino ORM (https://python-gino.org/),
3030
* Tortoise ORM (https://tortoise-orm.readthedocs.io/en/latest/),
31+
* Encode ORM (https://github.com/encode/orm)
3132
* Django ORM Model (https://docs.djangoproject.com/en/3.2/topics/db/queries/),
3233
* Pydantic (https://pydantic-docs.helpmanual.io/),
3334
* Python Enum (https://docs.python.org/3/library/enum.html),
3435
* Pony ORM (https://ponyorm.org/),
36+
* Piccolo ORM models (https://piccolo-orm.readthedocs.io/en/latest/piccolo/schema/defining.html),
3537
* Pydal Tables definitions (http://www.web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#The-DAL-A-quick-tour),
3638
* Python Dataclasses (https://docs.python.org/3/library/dataclasses.html),
3739
* pure Python Classes (https://docs.python.org/3/tutorial/classes.html#class-objects)
@@ -194,13 +196,19 @@ TODO: in next Release
194196
---------------------
195197

196198

197-
#. Add more tests for supported models (and fix existed not covered cases): Django ORM, Pydantic, Enums, Dataclasses, SQLAlchemy Models, GinoORM models, TortoiseORM models, PonyORM, for lists
199+
#. Add more tests for supported models
198200
#. Add support for SQLAlchemy Core Tables
199-
#. Add support for Piccolo ORM models
200201

201202
Changelog
202203
---------
203204

205+
**v0.6.0**
206+
Features:
207+
208+
209+
#. Added support for Encode ORM models https://github.com/encode/orm
210+
#. Added support for Piccolo ORM models https://piccolo-orm.readthedocs.io/en/latest/piccolo/schema/defining.html
211+
204212
**v0.5.1**
205213
Fixes:
206214

py_models_parser/core.py

+48
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,58 @@ def output(input: str):
6262
return output
6363

6464

65+
def process_models_attr(model: Dict, models_by_name: Dict) -> Dict:
66+
for attr in model["attrs"]:
67+
if (
68+
attr.get("properties")
69+
and attr["properties"].get("foreign_key")
70+
and not attr["properties"].get("through")
71+
):
72+
split_type = attr["type"].split(".")
73+
target_model = models_by_name.get(split_type[0])
74+
if target_model:
75+
key = [
76+
attr
77+
for attr in target_model["attrs"]
78+
if attr["name"] == split_type[1]
79+
]
80+
if not key:
81+
_type = "serial"
82+
else:
83+
_type = key[0]["type"]
84+
attr["type"] = _type
85+
return model
86+
87+
88+
def clear_parents(model: Dict) -> Dict:
89+
90+
parents = []
91+
92+
for parent in model["parents"]:
93+
if "tablename" in parent:
94+
name = parent.split("=")
95+
model["properties"]["table_name"] = name[1]
96+
continue
97+
parents.append(parent)
98+
99+
model["parents"] = parents
100+
101+
return model
102+
103+
104+
def format_ouput(output: List[Dict]):
105+
models_by_name = {model["name"]: model for model in output}
106+
for model in output:
107+
model = process_models_attr(model, models_by_name)
108+
model = clear_parents(model)
109+
return output
110+
111+
65112
def parse(models: str) -> List[Dict]:
66113
models = pre_processing(models)
67114
result = grammar.parse(models)
68115
result = output(result)
116+
result = format_ouput(result)
69117
return result
70118

71119

py_models_parser/grammar.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
grammar = Grammar(
44
r"""
5-
expr = (class / if_else/ call_result / return / attr_def / emptyline / funct_def)*
5+
expr = (class / if_else/ call_result / return / comments / attr_def / emptyline / funct_def)*
66
return = "return" (id* ","*)*
7+
comments = "\#" (text / list)
78
if_else= ("if" (compare/ id / attr_def) ":")/("elif" (id/attr_def) ":")/("else" ":")
89
compare = (call_result / id / args /args_in_brackets ) operator (call_result/id/args_in_brackets/args)
910
operator = "==" / "!=" / ">" / "<" / ">=" / "<="

py_models_parser/visitor.py

+27-20
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
from parsimonious.nodes import NodeVisitor
44

55
from py_models_parser.parsers.pydal import process_pydal_table_definition
6+
from py_models_parser.types import (
7+
orm_triggers,
8+
ormar_and_piccollo_types,
9+
pony_orm_fields,
10+
)
611

712

813
class Visitor(NodeVisitor):
@@ -46,30 +51,26 @@ def clean_up_cases_with_inner_pars(text: str) -> str:
4651
pass
4752
return text
4853

54+
def ormar_and_piccollo_info(
55+
self, text: List[str], i: str, properties: Dict
56+
) -> Tuple[str, Dict]:
57+
default = None
58+
_type = i
59+
for text_str in text:
60+
data = text_str.split("=")
61+
if len(data) == 2:
62+
if data[0] == "default":
63+
default = data[1].strip()
64+
else:
65+
properties[data[0].strip()] = data[1].strip()
66+
return _type, properties, default
67+
4968
def extract_orm_attr(self, text: str):
5069
_type = None
5170
default = None
5271
not_orm = True
5372
properties = {}
54-
orm_triggers = ["Column", "Field", "relationship", "ForeignKey"]
55-
pony_orm_fields = ["Required", "Set", "Optional", "PrimaryKey"]
56-
ormar_types = [
57-
"Integer",
58-
"String",
59-
"Text",
60-
"Boolean",
61-
"BigInteger",
62-
"SmallInteger",
63-
"Float",
64-
"Decimal",
65-
"Date",
66-
"Time",
67-
"JSON",
68-
"DateTime",
69-
"LargeBinary",
70-
]
71-
orm_triggers.extend(pony_orm_fields)
72-
orm_triggers.extend(ormar_types)
73+
7374
for i in orm_triggers:
7475
if i in text:
7576
not_orm = False
@@ -85,11 +86,15 @@ def extract_orm_attr(self, text: str):
8586
prop_index = 0
8687
elif i == "ForeignKey":
8788
# mean it is a Django model.ForeignKey
88-
_type = "serial"
89+
_type = f"{text[0]}.id"
8990
properties["foreign_key"] = text[0]
9091
elif i in pony_orm_fields:
9192
# mean it is a Pony ORM
9293
_type, properties = get_pony_orm_info(text, i, properties)
94+
elif i in ormar_and_piccollo_types:
95+
_type, properties, default = self.ormar_and_piccollo_info(
96+
text, i, properties
97+
)
9398
else:
9499
_type = text[0]
95100
if i == "relationship":
@@ -169,6 +174,8 @@ def _process_attr(attr: Dict, final_item: Dict) -> Dict:
169174
final_item["properties"]["init"] = []
170175
elif "tablename" in attr["name"]:
171176
final_item["properties"]["table_name"] = attr["default"]
177+
elif attr["name"] in ["__database__", "__metadata__"]:
178+
final_item["properties"][attr["name"]] = attr["default"]
172179
elif "table_args" in attr["name"]:
173180
final_item["properties"][attr["name"]] = attr["type"] or attr["default"]
174181
else:

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "py-models-parser"
3-
version = "0.5.1"
3+
version = "0.6.0"
44
description = "Parser for Different Python Models (Pydantic, Enums, ORMs: Tortoise, SqlAlchemy, GinoORM, PonyORM, Pydal tables) to extract information about columns(attrs), model, table args,etc in one format."
55
authors = ["Iuliia Volkova <xnuinside@gmail.com>"]
66
license = "MIT"

0 commit comments

Comments
 (0)