ajuste de cruds incompleto

This commit is contained in:
2026-04-06 16:06:31 -07:00
parent 61d386a7c7
commit 290a32364d
75 changed files with 3574 additions and 26 deletions

179
generator.py Normal file
View File

@@ -0,0 +1,179 @@
""" Generate service files "service and route", CRUD.
READ models on a modules, and generate code usin template Jija2
"""
import os
from pathlib import Path
from typing import Dict, List, Any
# #
from jinja2 import Environment, FileSystemLoader
from sqlalchemy import inspect, Table, Column
from sqlalchemy.engine import create_mock_engine
#####
from database import Base
import importlib
import enum
class CodeGenerator:
def __init__(self, templates_dir: str = "templates", output_dir: str = "generated"):
self.templates_dir = Path(templates_dir)
self.output_dir = Path(output_dir)
self.env = Environment(loader=FileSystemLoader(templates_dir))
# create directory of output
self.output_dir.mkdir(parents=True, exist_ok=True)
(self.output_dir / "services").mkdir(exist_ok=True)
(self.output_dir / "routes").mkdir(exist_ok=True)
(self.output_dir / "schemas").mkdir(exist_ok=True)
def get_model_metadata(self, model_class) -> Dict[str, Any]:
"""" Extract metadata from SQLAlchemy """
if not hasattr(model_class, '__table__'):
print(f"{model_class.__name__} no tiene __table__, jumping")
return None
fields = []
required_fields = []
unique_fields = []
for column in model_class.__table__.columns:
column_type = str(column.type)
if 'enum' in column_type.lower() or 'ENUM' in column_type:
# extract possible values of enum
if hasattr(column.type, 'enum_class'):
enum_values = list(column.type.enum_class.__members__.keys())
python_type = "str"
else:
python_type = "str"
else:
python_type = self._sqlalchemy_to_python_type(column.type)
field_info = {
"name": column.name,
"type": column_type,
"python_type": python_type,
"nullable": column.nullable ,
"primary_key": column.primary_key,
"unique": column.unique,
"default": column.default is None,
"is_enum": 'enum' in column_type.lower(),
}
fields.append(field_info)
if not column.nullable and not column.primary_key:
required_fields.append(column.name)
if column.unique:
unique_fields.append(column.name)
return{
"class_name" : model_class.__name__,
"entity_name" : model_class.__name__.lower(),
"model_name" : model_class.__name__,
"model_folder" : model_class.__module__.split(".")[-2] if "." in model_class.__module__ else "models",
"schema_folder" : "schemas" ,
"fields" : fields,
"required_fields" : required_fields,
"unique_fields" : unique_fields,
"has_soft_delete" : any(c.name in ["is_active", "deleted_at"] for c in model_class.__table__.columns),
}
def _sqlalchemy_to_python_type(self, sqlalchemy_type) -> str:
""" Convert SQAlchemy types on a python"""
type_str = str(sqlalchemy_type).lower()
if "int" in type_str:
return "int"
elif "str" in type_str or "varchar" in type_str or "text" in type_str:
return "str"
elif "bool" in type_str:
return "bool"
elif "datetime" in type_str or "date" in type_str:
return "datetime"
elif "float" in type_str or "decimal" in type_str:
return "float"
else:
return "Any"
def generate_service(self, model_metada: Dict[str, Any]):
""" Generate file of service using template"""
template = self.env.get_template("service_template.j2")
output = template.render(**model_metada)
output_file = self.output_dir / "services" /f"{model_metada['entity_name']}_service.py"
with open(output_file, "w", encoding="utf-8") as f:
f.write(output)
print(f"Generated: {output_file}")
def generate_route(self, model_metadata: Dict[str, Any]):
"""Generate file of route using template"""
template = self.env.get_template("route_template.j2")
output = template.render(**model_metadata)
output_file = self.output_dir / "routers" / f"{model_metadata['entity_name']}_router.py"
with open(output_file, "w", encoding="utf-8") as f:
f.write(output)
print(f"Generated: {output_file}")
def generate_all(self, models_list: List):
""" Generate services and router for a list models"""
print(f"Intializing generation")
for model in models_list:
print(f"Processing model: {model.__name__}")
metadata = self.get_model_metadata(model)
if metadata is None:
print(f"Error: can't obtain metadara, jumped \n")
continue
self.generate_service(metadata)
self.generate_route(metadata)
print("Generation completed")
def get_all_models():
"""Import and retunr all models SQLAlchemy"""
from app.modules.coments.models import Coments
from app.modules.configuration.models import Configuration
from app.modules.credits.models import Credits
from app.modules.edos.models import EDOS
from app.modules.efos.models import EFOS
from app.modules.feed.models import Feed
from app.modules.files.models import Files
from app.modules.interactions.models import Interaccion
from app.modules.invoices.models import Invoices
from app.modules.license.models import License
from app.modules.moves.models import Moves
from app.modules.location.models import Locations
from app.modules.suppliers.models import Suppliers
from app.modules.branches.models import Branches
return [Branches, Coments, Configuration, Credits, EDOS, EFOS, Feed, Files, Interaccion, Invoices, License, Moves, Locations, Suppliers]
def main():
#configure routes
generator = CodeGenerator(
templates_dir = "templates",
output_dir = "output/generated"
)
models = get_all_models()
generator.generate_all(models)
if __name__ == "__main__":
main()