1+ from __future__ import annotations
2+
13import dataclasses
24import typing as t
35
68
79from piccolo .columns .base import Column
810from piccolo .columns .column_types import (
11+ JSON ,
12+ JSONB ,
913 UUID ,
1014 BigInt ,
1115 Boolean ,
16+ Bytea ,
17+ Date ,
1218 Integer ,
19+ Interval ,
1320 Numeric ,
21+ Real ,
1422 SmallInt ,
1523 Text ,
1624 Timestamp ,
@@ -50,16 +58,47 @@ def get_column_name_str(cls) -> str:
5058 return ", " .join ([i .name for i in dataclasses .fields (cls )])
5159
5260
61+ @dataclasses .dataclass
62+ class OutputSchema :
63+ """
64+ Represents the schema which will printed output.
65+
66+ :param imports:
67+ e.g. ["from piccolo.table import Table"]
68+ :param warnings:
69+ e.g. ["some_table.some_column unrecognised_type"]
70+ :param tables:
71+ e.g. ["class MyTable(Table): ..."]
72+
73+ """
74+
75+ imports : t .List [str ]
76+ warnings : t .List [str ]
77+ tables : t .List [t .Type [Table ]]
78+
79+ def get_table_with_name (self , name : str ) -> t .Type [Table ]:
80+ """
81+ Just used by unit tests.
82+ """
83+ return next (table for table in self .tables if table .__name__ == name )
84+
85+
5386COLUMN_TYPE_MAP = {
5487 "bigint" : BigInt ,
5588 "boolean" : Boolean ,
89+ "bytea" : Bytea ,
5690 "character varying" : Varchar ,
91+ "date" : Date ,
5792 "integer" : Integer ,
93+ "interval" : Interval ,
94+ "json" : JSON ,
95+ "jsonb" : JSONB ,
5896 "numeric" : Numeric ,
97+ "real" : Real ,
5998 "smallint" : SmallInt ,
6099 "text" : Text ,
61- "timestamp without time zone" : Timestamp ,
62100 "timestamp with time zone" : Timestamptz ,
101+ "timestamp without time zone" : Timestamp ,
63102 "uuid" : UUID ,
64103}
65104
@@ -129,15 +168,7 @@ async def get_table_schema(
129168 return [PostgresRowMeta (** row_meta ) for row_meta in row_meta_list ]
130169
131170
132- # This is currently a beta version, and can be improved. However, having
133- # something working is still useful for people migrating large schemas to
134- # Piccolo.
135- async def generate (schema_name : str = "public" ):
136- """
137- Automatically generates Piccolo Table classes by introspecting the
138- database. Please check the generated code in case there are errors.
139-
140- """
171+ async def get_output_schema (schema_name : str = "public" ) -> OutputSchema :
141172 engine : t .Optional [Engine ] = engine_finder ()
142173
143174 if engine is None :
@@ -152,11 +183,15 @@ async def generate(schema_name: str = "public"):
152183 )
153184
154185 class Schema (Table , db = engine ):
186+ """
187+ Just used for making raw queries on the db.
188+ """
189+
155190 pass
156191
157192 tablenames = await get_tablenames (Schema , schema_name = schema_name )
158193
159- output : t .List [str ] = []
194+ tables : t .List [t . Type [ Table ] ] = []
160195 imports : t .Set [str ] = {"from piccolo.table import Table" }
161196 warnings : t .List [str ] = []
162197
@@ -191,12 +226,30 @@ class Schema(Table, db=engine):
191226 class_kwargs = {"tablename" : tablename },
192227 class_members = columns ,
193228 )
194- output .append (table ._table_str ())
229+ tables .append (table )
230+
231+ return OutputSchema (
232+ imports = sorted (list (imports )), warnings = warnings , tables = tables
233+ )
234+
235+
236+ # This is currently a beta version, and can be improved. However, having
237+ # something working is still useful for people migrating large schemas to
238+ # Piccolo.
239+ async def generate (schema_name : str = "public" ):
240+ """
241+ Automatically generates Piccolo Table classes by introspecting the
242+ database. Please check the generated code in case there are errors.
243+
244+ """
245+ output_schema = await get_output_schema (schema_name = schema_name )
195246
196- output = sorted (list (imports )) + output
247+ output = output_schema .imports + [
248+ i ._table_str () for i in output_schema .tables
249+ ]
197250
198- if warnings :
199- warning_str = "\n " .join (warnings )
251+ if output_schema . warnings :
252+ warning_str = "\n " .join (output_schema . warnings )
200253
201254 output .append ('"""' )
202255 output .append (
0 commit comments