bedrock.generators.code_generators.model.model_class
1from typing import Optional 2 3from bedrock._helpers.string import camelCase_to_snake_case, as_plural 4from bedrock.generators.code_generators.model.helpers import resolve_model_name_from_path_hint 5from bedrock.generators.code_generators.common.imports import import_models 6 7 8def make_model_class(model_name: str, attributes: list[tuple[str, str]], project_name: str, path_hint: str, 9 table_name: str, app_path: str) -> tuple[str, dict]: 10 if path_hint: 11 lines = [f"@filter_path_hint(\"{path_hint}\")"] 12 else: 13 lines = [] 14 _table_name = table_name if table_name else f"{project_name}_{camelCase_to_snake_case(model_name).lower()}" 15 lines.extend([ 16 f"class {model_name}(Base, ModelHelper): # pragma: unit", 17 f" __tablename__ = \"{_table_name}\"", 18 "" 19 ]) 20 foreign_key, relationship, reverse_back_populate = make_foreign_key_attributes(model_name, path_hint, app_path) 21 if foreign_key: 22 lines.append(f" {foreign_key}") 23 for attribute in attributes: 24 lines.append(f" {attribute[0]} = Column({attribute[1]})") 25 if relationship: 26 lines.append("") 27 lines.append(f" {relationship}") 28 29 return "\n".join(lines), reverse_back_populate 30 31 32def make_foreign_key_attributes(model_name: str, path_hint: str, app_path: str) -> \ 33 tuple[Optional[str], Optional[str], dict]: 34 if not path_hint: 35 return None, None, {} 36 hinted_model_name = resolve_model_name_from_path_hint(path_hint) 37 hinted_model = import_models(app_path).get(hinted_model_name) 38 if not hinted_model: 39 return None, None, {} 40 hinted_model_table_name = hinted_model.__tablename__ 41 relationship_attribute = camelCase_to_snake_case(hinted_model_name) 42 foreign_key_attribute = f"{relationship_attribute}_uuid" 43 back_populated_attribute = as_plural(camelCase_to_snake_case(model_name)) 44 45 relationship = f'{relationship_attribute} = relationship("{hinted_model_name}", lazy="joined", back_populates="{back_populated_attribute}")' 46 relationship_comment = f"TODO: In {hinted_model_name}, please check that {back_populated_attribute} is correctly linking back to {relationship_attribute}" 47 reverse_back_populate = f"{back_populated_attribute} = relationship(\"{model_name}\", lazy=\"joined\")" 48 return ( 49 f'{foreign_key_attribute} = Column(UUID(as_uuid=True), ForeignKey("{hinted_model_table_name}.uuid", ondelete="cascade"), nullable=False)', 50 f'{relationship} # {relationship_comment}', 51 {"line": reverse_back_populate, "model": hinted_model_name} if hinted_model_name else {} 52 )
def
make_model_class( model_name: str, attributes: list[tuple[str, str]], project_name: str, path_hint: str, table_name: str, app_path: str) -> tuple[str, dict]:
9def make_model_class(model_name: str, attributes: list[tuple[str, str]], project_name: str, path_hint: str, 10 table_name: str, app_path: str) -> tuple[str, dict]: 11 if path_hint: 12 lines = [f"@filter_path_hint(\"{path_hint}\")"] 13 else: 14 lines = [] 15 _table_name = table_name if table_name else f"{project_name}_{camelCase_to_snake_case(model_name).lower()}" 16 lines.extend([ 17 f"class {model_name}(Base, ModelHelper): # pragma: unit", 18 f" __tablename__ = \"{_table_name}\"", 19 "" 20 ]) 21 foreign_key, relationship, reverse_back_populate = make_foreign_key_attributes(model_name, path_hint, app_path) 22 if foreign_key: 23 lines.append(f" {foreign_key}") 24 for attribute in attributes: 25 lines.append(f" {attribute[0]} = Column({attribute[1]})") 26 if relationship: 27 lines.append("") 28 lines.append(f" {relationship}") 29 30 return "\n".join(lines), reverse_back_populate
def
make_foreign_key_attributes( model_name: str, path_hint: str, app_path: str) -> tuple[typing.Optional[str], typing.Optional[str], dict]:
33def make_foreign_key_attributes(model_name: str, path_hint: str, app_path: str) -> \ 34 tuple[Optional[str], Optional[str], dict]: 35 if not path_hint: 36 return None, None, {} 37 hinted_model_name = resolve_model_name_from_path_hint(path_hint) 38 hinted_model = import_models(app_path).get(hinted_model_name) 39 if not hinted_model: 40 return None, None, {} 41 hinted_model_table_name = hinted_model.__tablename__ 42 relationship_attribute = camelCase_to_snake_case(hinted_model_name) 43 foreign_key_attribute = f"{relationship_attribute}_uuid" 44 back_populated_attribute = as_plural(camelCase_to_snake_case(model_name)) 45 46 relationship = f'{relationship_attribute} = relationship("{hinted_model_name}", lazy="joined", back_populates="{back_populated_attribute}")' 47 relationship_comment = f"TODO: In {hinted_model_name}, please check that {back_populated_attribute} is correctly linking back to {relationship_attribute}" 48 reverse_back_populate = f"{back_populated_attribute} = relationship(\"{model_name}\", lazy=\"joined\")" 49 return ( 50 f'{foreign_key_attribute} = Column(UUID(as_uuid=True), ForeignKey("{hinted_model_table_name}.uuid", ondelete="cascade"), nullable=False)', 51 f'{relationship} # {relationship_comment}', 52 {"line": reverse_back_populate, "model": hinted_model_name} if hinted_model_name else {} 53 )