@@ -45,6 +45,7 @@ def create_models(
4545 table_prefix : Optional [str ] = "" ,
4646 table_suffix : Optional [str ] = "" ,
4747 relationships : Optional [bool ] = False ,
48+ split_by_schema : Optional [bool ] = False ,
4849):
4950 """models_type can be: "gino", "dataclass", "pydantic" """
5051 # extract data from ddl file
@@ -56,7 +57,28 @@ def create_models(
5657 sys .exit (0 )
5758 else :
5859 raise NoTablesError ()
59- # generate code
60+
61+ # Handle split_by_schema mode
62+ if split_by_schema :
63+ output = generate_models_by_schema (
64+ data ,
65+ singular ,
66+ naming_exceptions ,
67+ models_type ,
68+ defaults_off ,
69+ table_prefix = table_prefix ,
70+ table_suffix = table_suffix ,
71+ relationships = relationships ,
72+ )
73+ if dump :
74+ save_models_by_schema (output , dump_path )
75+ else :
76+ for schema_name , code in output .items ():
77+ print (f"# === { schema_name } ===" )
78+ print (code )
79+ return {"metadata" : data , "code" : output }
80+
81+ # generate code (single file mode)
6082 output = generate_models_file (
6183 data ,
6284 singular ,
@@ -140,6 +162,104 @@ def save_models_to_file(models: str, dump_path: str) -> None:
140162 f .write (models )
141163
142164
165+ def save_models_by_schema (models_by_schema : Dict [str , str ], dump_path : str ) -> None :
166+ """Save models split by schema to separate files."""
167+ folder = os .path .dirname (dump_path )
168+ base_name = os .path .basename (dump_path )
169+ name_without_ext = os .path .splitext (base_name )[0 ]
170+
171+ if folder :
172+ os .makedirs (folder , exist_ok = True )
173+
174+ for schema_name , code in models_by_schema .items ():
175+ file_name = f"{ schema_name } _{ name_without_ext } .py" if schema_name else f"{ name_without_ext } .py"
176+ file_path = os .path .join (folder , file_name ) if folder else file_name
177+ with open (file_path , "w+" ) as f :
178+ f .write (code )
179+
180+
181+ def group_tables_by_schema (tables : List ) -> Dict [str , List ]:
182+ """Group tables by their schema attribute."""
183+ grouped = {}
184+ for table in tables :
185+ schema = table .table_schema or ""
186+ grouped .setdefault (schema , []).append (table )
187+ return grouped
188+
189+
190+ def _schema_to_base_name (schema : str ) -> str :
191+ """Convert schema name to Base class name (e.g., 'my_schema' -> 'MySchemaBase')."""
192+ if not schema :
193+ return "Base"
194+ # Convert snake_case or kebab-case to PascalCase
195+ parts = schema .replace ("-" , "_" ).split ("_" )
196+ pascal = "" .join (part .capitalize () for part in parts )
197+ return f"{ pascal } Base"
198+
199+
200+ def generate_models_by_schema (
201+ data : Dict [str , List ],
202+ singular : bool = False ,
203+ exceptions : Optional [List ] = None ,
204+ models_type : str = "gino" ,
205+ defaults_off : Optional [bool ] = False ,
206+ table_prefix : Optional [str ] = "" ,
207+ table_suffix : Optional [str ] = "" ,
208+ relationships : Optional [bool ] = False ,
209+ ) -> Dict [str , str ]:
210+ """Generate models split by schema, each with its own Base class."""
211+ from omymodels .generators import get_generator_by_type , render_jinja2_template
212+
213+ results = {}
214+ tables_by_schema = group_tables_by_schema (data ["tables" ])
215+
216+ # Collect relationships across all tables if enabled
217+ relationships_map = {}
218+ if relationships :
219+ relationships_map = collect_relationships (data ["tables" ])
220+
221+ for schema_name , tables in tables_by_schema .items ():
222+ generator = get_generator_by_type (models_type )
223+ add_custom_types_to_generator (data ["types" ], generator )
224+
225+ models_str = ""
226+ header = ""
227+
228+ # Include types only in the first (or default) schema file
229+ if data ["types" ] and schema_name == "" :
230+ types_generator = enum .ModelGenerator (data ["types" ])
231+ models_str += types_generator .create_types ()
232+ header += types_generator .create_header ()
233+
234+ for table in tables :
235+ models_str += generator .generate_model (
236+ table ,
237+ singular ,
238+ exceptions ,
239+ schema_global = False , # Always include schema in __table_args__
240+ defaults_off = defaults_off ,
241+ table_prefix = table_prefix ,
242+ table_suffix = table_suffix ,
243+ relationships = relationships_map .get (table .name , []) if relationships else [],
244+ )
245+
246+ header += generator .create_header (tables , schema = False , models_str = models_str )
247+
248+ # Generate code with schema-specific Base name
249+ base_name = _schema_to_base_name (schema_name )
250+ output = render_jinja2_template (
251+ models_type , models_str , header , base_name = base_name
252+ )
253+
254+ # Replace class inheritance from Base to custom base name
255+ if base_name != "Base" :
256+ output = output .replace ("(Base):" , f"({ base_name } ):" )
257+
258+ results [schema_name ] = output
259+
260+ return results
261+
262+
143263def _add_relationship (
144264 relationships : Dict , table_name : str , fk_column : str , ref_table : str , ref_column : str
145265):
0 commit comments