pyoq-sql 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyoq/__init__.py +10 -0
- pyoq/__main__.py +5 -0
- pyoq/_native.pyi +5 -0
- pyoq/cli/__init__.py +5 -0
- pyoq/cli/commands.py +270 -0
- pyoq/cli/defaults.py +98 -0
- pyoq/cli/services.py +97 -0
- pyoq/config/__init__.py +31 -0
- pyoq/config/connection.py +161 -0
- pyoq/config/loader.py +289 -0
- pyoq/config/models.py +245 -0
- pyoq/config/values.py +142 -0
- pyoq/descriptors.py +165 -0
- pyoq/diagnostics/__init__.py +68 -0
- pyoq/diagnostics/budget.py +136 -0
- pyoq/diagnostics/events.py +137 -0
- pyoq/diagnostics/fingerprint.py +267 -0
- pyoq/diagnostics/instrumented.py +237 -0
- pyoq/diagnostics/metrics.py +61 -0
- pyoq/diagnostics/observation.py +227 -0
- pyoq/diagnostics/scoped.py +103 -0
- pyoq/django/__init__.py +15 -0
- pyoq/django/apps.py +17 -0
- pyoq/django/execution.py +317 -0
- pyoq/django/generation.py +59 -0
- pyoq/django/management/__init__.py +0 -0
- pyoq/django/management/commands/__init__.py +0 -0
- pyoq/django/management/commands/makemigrations.py +53 -0
- pyoq/django/management/commands/pyoq_codegen.py +75 -0
- pyoq/django/parameters.py +101 -0
- pyoq/django/schema.py +379 -0
- pyoq/django/settings.py +87 -0
- pyoq/django/timeouts.py +105 -0
- pyoq/dsl/__init__.py +64 -0
- pyoq/dsl/aio/__init__.py +31 -0
- pyoq/dsl/aio/context.py +295 -0
- pyoq/dsl/aio/queries.py +335 -0
- pyoq/dsl/aio/writes.py +368 -0
- pyoq/dsl/context.py +326 -0
- pyoq/dsl/entry.py +37 -0
- pyoq/dsl/labels.py +36 -0
- pyoq/dsl/queries.py +339 -0
- pyoq/dsl/result.py +164 -0
- pyoq/dsl/writes.py +360 -0
- pyoq/errors.py +317 -0
- pyoq/fastapi/__init__.py +32 -0
- pyoq/fastapi/dependencies.py +167 -0
- pyoq/fastapi/lifespan.py +119 -0
- pyoq/fetching/__init__.py +55 -0
- pyoq/fetching/collections.py +136 -0
- pyoq/fetching/execution.py +587 -0
- pyoq/fetching/joined.py +79 -0
- pyoq/fetching/nesting.py +183 -0
- pyoq/fetching/plans.py +541 -0
- pyoq/fetching/select_in.py +149 -0
- pyoq/fetching/tables.py +110 -0
- pyoq/generation/__init__.py +54 -0
- pyoq/generation/cleanup.py +44 -0
- pyoq/generation/contracts.py +248 -0
- pyoq/generation/drift.py +169 -0
- pyoq/generation/lock.py +33 -0
- pyoq/generation/manifest.py +114 -0
- pyoq/generation/model.py +1001 -0
- pyoq/generation/pipeline.py +119 -0
- pyoq/generation/rendering/__init__.py +5 -0
- pyoq/generation/rendering/domains.py +51 -0
- pyoq/generation/rendering/enums.py +29 -0
- pyoq/generation/rendering/exports.py +70 -0
- pyoq/generation/rendering/imports.py +63 -0
- pyoq/generation/rendering/package.py +56 -0
- pyoq/generation/rendering/relations.py +133 -0
- pyoq/generation/rendering/routines.py +396 -0
- pyoq/generation/rendering/rows.py +79 -0
- pyoq/generation/rendering/source.py +121 -0
- pyoq/generation/rendering/tables.py +300 -0
- pyoq/generation/rendering/writes.py +514 -0
- pyoq/generation/validation.py +27 -0
- pyoq/generation/writer.py +184 -0
- pyoq/hydration/__init__.py +24 -0
- pyoq/hydration/engine.py +155 -0
- pyoq/hydration/identity.py +194 -0
- pyoq/hydration/plan.py +116 -0
- pyoq/migrations/__init__.py +9 -0
- pyoq/migrations/alembic.py +106 -0
- pyoq/migrations/hooks.py +75 -0
- pyoq/naming.py +261 -0
- pyoq/policies/__init__.py +47 -0
- pyoq/policies/bypass.py +122 -0
- pyoq/policies/governed.py +430 -0
- pyoq/policies/model.py +242 -0
- pyoq/policies/rewriting.py +263 -0
- pyoq/py.typed +1 -0
- pyoq/query/__init__.py +312 -0
- pyoq/query/aggregates.py +172 -0
- pyoq/query/arrays.py +65 -0
- pyoq/query/binding.py +52 -0
- pyoq/query/capabilities.py +317 -0
- pyoq/query/casts.py +73 -0
- pyoq/query/choices.py +185 -0
- pyoq/query/decoding.py +360 -0
- pyoq/query/documents.py +56 -0
- pyoq/query/execution/__init__.py +63 -0
- pyoq/query/execution/aio/__init__.py +31 -0
- pyoq/query/execution/aio/operations.py +228 -0
- pyoq/query/execution/aio/pooling.py +233 -0
- pyoq/query/execution/aio/streaming.py +161 -0
- pyoq/query/execution/aio/transactions.py +105 -0
- pyoq/query/execution/batch.py +96 -0
- pyoq/query/execution/binding_style.py +30 -0
- pyoq/query/execution/compilation.py +48 -0
- pyoq/query/execution/context.py +61 -0
- pyoq/query/execution/control.py +50 -0
- pyoq/query/execution/operations.py +224 -0
- pyoq/query/execution/planning.py +107 -0
- pyoq/query/execution/pooling.py +279 -0
- pyoq/query/execution/results.py +36 -0
- pyoq/query/execution/streaming.py +178 -0
- pyoq/query/execution/transactions.py +95 -0
- pyoq/query/expressions.py +1200 -0
- pyoq/query/fields.py +60 -0
- pyoq/query/mysql/__init__.py +59 -0
- pyoq/query/mysql/aio/__init__.py +38 -0
- pyoq/query/mysql/aio/commands.py +389 -0
- pyoq/query/mysql/aio/driver.py +196 -0
- pyoq/query/mysql/aio/executor.py +123 -0
- pyoq/query/mysql/aio/factory.py +26 -0
- pyoq/query/mysql/aio/operations.py +38 -0
- pyoq/query/mysql/aio/pool.py +53 -0
- pyoq/query/mysql/aio/transactions.py +313 -0
- pyoq/query/mysql/commands.py +354 -0
- pyoq/query/mysql/compiler.py +134 -0
- pyoq/query/mysql/context.py +20 -0
- pyoq/query/mysql/executor.py +126 -0
- pyoq/query/mysql/expressions.py +244 -0
- pyoq/query/mysql/factory.py +46 -0
- pyoq/query/mysql/health.py +66 -0
- pyoq/query/mysql/identifiers.py +9 -0
- pyoq/query/mysql/model.py +79 -0
- pyoq/query/mysql/operations.py +43 -0
- pyoq/query/mysql/parameters.py +69 -0
- pyoq/query/mysql/planning.py +20 -0
- pyoq/query/mysql/pool.py +67 -0
- pyoq/query/mysql/transactions.py +331 -0
- pyoq/query/mysql/writes.py +73 -0
- pyoq/query/nodes.py +750 -0
- pyoq/query/postgres/__init__.py +48 -0
- pyoq/query/postgres/aio/__init__.py +25 -0
- pyoq/query/postgres/aio/bulk.py +56 -0
- pyoq/query/postgres/aio/commands.py +264 -0
- pyoq/query/postgres/aio/executor.py +152 -0
- pyoq/query/postgres/aio/factory.py +26 -0
- pyoq/query/postgres/aio/operations.py +26 -0
- pyoq/query/postgres/aio/pool.py +40 -0
- pyoq/query/postgres/aio/transactions.py +295 -0
- pyoq/query/postgres/bulk.py +62 -0
- pyoq/query/postgres/commands.py +238 -0
- pyoq/query/postgres/compiler.py +114 -0
- pyoq/query/postgres/context.py +20 -0
- pyoq/query/postgres/executor.py +147 -0
- pyoq/query/postgres/expressions.py +311 -0
- pyoq/query/postgres/factory.py +24 -0
- pyoq/query/postgres/health.py +24 -0
- pyoq/query/postgres/identifiers.py +9 -0
- pyoq/query/postgres/model.py +81 -0
- pyoq/query/postgres/operations.py +25 -0
- pyoq/query/postgres/parameters.py +71 -0
- pyoq/query/postgres/planning.py +20 -0
- pyoq/query/postgres/pool.py +52 -0
- pyoq/query/postgres/transactions.py +295 -0
- pyoq/query/postgres/writes.py +37 -0
- pyoq/query/projections.py +105 -0
- pyoq/query/raw.py +90 -0
- pyoq/query/recursion.py +265 -0
- pyoq/query/rendering/__init__.py +1 -0
- pyoq/query/rendering/expressions.py +913 -0
- pyoq/query/rendering/identifiers.py +40 -0
- pyoq/query/rendering/projections.py +63 -0
- pyoq/query/rendering/queries.py +334 -0
- pyoq/query/rendering/sources.py +66 -0
- pyoq/query/rendering/writes.py +176 -0
- pyoq/query/results.py +459 -0
- pyoq/query/routines.py +196 -0
- pyoq/query/rows.py +156 -0
- pyoq/query/select.py +793 -0
- pyoq/query/select_nodes.py +277 -0
- pyoq/query/sources.py +236 -0
- pyoq/query/sqlite/__init__.py +43 -0
- pyoq/query/sqlite/commands.py +201 -0
- pyoq/query/sqlite/compiler.py +139 -0
- pyoq/query/sqlite/context.py +20 -0
- pyoq/query/sqlite/executor.py +119 -0
- pyoq/query/sqlite/expressions.py +224 -0
- pyoq/query/sqlite/factory.py +32 -0
- pyoq/query/sqlite/health.py +28 -0
- pyoq/query/sqlite/identifiers.py +9 -0
- pyoq/query/sqlite/model.py +73 -0
- pyoq/query/sqlite/operations.py +36 -0
- pyoq/query/sqlite/parameters.py +50 -0
- pyoq/query/sqlite/planning.py +20 -0
- pyoq/query/sqlite/pool.py +50 -0
- pyoq/query/sqlite/streaming.py +13 -0
- pyoq/query/sqlite/transactions.py +274 -0
- pyoq/query/sqlite/writes.py +35 -0
- pyoq/query/statements.py +27 -0
- pyoq/query/values.py +23 -0
- pyoq/query/vendor.py +162 -0
- pyoq/query/windows.py +424 -0
- pyoq/query/write_nodes.py +174 -0
- pyoq/query/writes.py +628 -0
- pyoq/relations/__init__.py +66 -0
- pyoq/relations/batching.py +219 -0
- pyoq/relations/derivation.py +111 -0
- pyoq/relations/fetching.py +355 -0
- pyoq/relations/graph.py +245 -0
- pyoq/relations/loading.py +74 -0
- pyoq/relations/model.py +75 -0
- pyoq/relations/planning.py +206 -0
- pyoq/runtime/__init__.py +9 -0
- pyoq/runtime/kernels.py +25 -0
- pyoq/runtime/python.py +43 -0
- pyoq/runtime/selection.py +73 -0
- pyoq/sanic/__init__.py +32 -0
- pyoq/sanic/scope.py +197 -0
- pyoq/sanic/workers.py +129 -0
- pyoq/schema/__init__.py +108 -0
- pyoq/schema/codec.py +711 -0
- pyoq/schema/models.py +604 -0
- pyoq/schema/mysql/__init__.py +16 -0
- pyoq/schema/mysql/connection.py +73 -0
- pyoq/schema/mysql/dsn.py +72 -0
- pyoq/schema/mysql/records.py +354 -0
- pyoq/schema/mysql/reflection.py +309 -0
- pyoq/schema/mysql/source.py +30 -0
- pyoq/schema/mysql/sql.py +128 -0
- pyoq/schema/mysql/types.py +105 -0
- pyoq/schema/postgres/__init__.py +13 -0
- pyoq/schema/postgres/connection.py +63 -0
- pyoq/schema/postgres/records.py +384 -0
- pyoq/schema/postgres/reflection.py +466 -0
- pyoq/schema/postgres/source.py +30 -0
- pyoq/schema/postgres/sql.py +246 -0
- pyoq/schema/postgres/types.py +98 -0
- pyoq/schema/registry.py +45 -0
- pyoq/schema/source.py +15 -0
- pyoq/schema/sqlite/__init__.py +6 -0
- pyoq/schema/sqlite/connection.py +54 -0
- pyoq/schema/sqlite/records.py +167 -0
- pyoq/schema/sqlite/reflection.py +393 -0
- pyoq/schema/sqlite/source.py +30 -0
- pyoq/schema/sqlite/sql.py +254 -0
- pyoq/schema/sqlite/types.py +74 -0
- pyoq/serving/__init__.py +23 -0
- pyoq/serving/databases.py +107 -0
- pyoq/serving/opening.py +331 -0
- pyoq/snapshots/__init__.py +20 -0
- pyoq/snapshots/drift.py +312 -0
- pyoq/snapshots/files.py +96 -0
- pyoq/snapshots/routing.py +40 -0
- pyoq/snapshots/source.py +33 -0
- pyoq/tracing/__init__.py +5 -0
- pyoq/tracing/spans.py +89 -0
- pyoq/unset.py +14 -0
- pyoq_sql-1.0.2.dist-info/METADATA +3050 -0
- pyoq_sql-1.0.2.dist-info/RECORD +267 -0
- pyoq_sql-1.0.2.dist-info/WHEEL +4 -0
- pyoq_sql-1.0.2.dist-info/entry_points.txt +3 -0
- pyoq_sql-1.0.2.dist-info/licenses/LICENSE +373 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"""Generated table and column descriptor source rendering."""
|
|
2
|
+
|
|
3
|
+
from pathlib import PurePosixPath
|
|
4
|
+
|
|
5
|
+
from pyoq.generation.contracts import RenderedFile
|
|
6
|
+
from pyoq.generation.model import GeneratedColumn, GeneratedPackage, GeneratedTable
|
|
7
|
+
from pyoq.generation.rendering.imports import plan_annotation_imports
|
|
8
|
+
from pyoq.generation.rendering.source import (
|
|
9
|
+
LINE_LIMIT,
|
|
10
|
+
PythonSource,
|
|
11
|
+
literal,
|
|
12
|
+
render_all,
|
|
13
|
+
render_from_import,
|
|
14
|
+
render_string_tuple,
|
|
15
|
+
render_subscript,
|
|
16
|
+
)
|
|
17
|
+
from pyoq.query.results import family_for_kind
|
|
18
|
+
from pyoq.schema import TypeKind
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def render_tables(package: GeneratedPackage) -> RenderedFile:
|
|
22
|
+
source = PythonSource()
|
|
23
|
+
source.line('"""Generated table and column descriptors."""')
|
|
24
|
+
source.line()
|
|
25
|
+
source.line("from __future__ import annotations")
|
|
26
|
+
if package.tables:
|
|
27
|
+
_render_imports(source, package)
|
|
28
|
+
for table in package.tables:
|
|
29
|
+
_render_table(source, table)
|
|
30
|
+
source.line()
|
|
31
|
+
source.line()
|
|
32
|
+
source.lines(render_all(_exported_names(package)))
|
|
33
|
+
return RenderedFile(PurePosixPath("tables.py"), source.render())
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _render_imports(source: PythonSource, package: GeneratedPackage) -> None:
|
|
37
|
+
annotations = plan_annotation_imports(_column_annotations(package), package)
|
|
38
|
+
source.line()
|
|
39
|
+
source.lines(tuple(sorted((*annotations.standard, "from typing import ClassVar"))))
|
|
40
|
+
source.line()
|
|
41
|
+
descriptor_names = ["ColumnDescriptor", "TableDescriptor"]
|
|
42
|
+
if any(table.keys for table in package.tables):
|
|
43
|
+
descriptor_names.append("KeyDescriptor")
|
|
44
|
+
if any(table.required_columns for table in package.tables):
|
|
45
|
+
descriptor_names.append("Missing")
|
|
46
|
+
descriptor_names.extend(annotations.descriptor_names)
|
|
47
|
+
source.lines(
|
|
48
|
+
render_from_import(
|
|
49
|
+
"pyoq.descriptors",
|
|
50
|
+
tuple(descriptor_names),
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
source.line("from pyoq.query import ScalarFamily")
|
|
54
|
+
if any(table.keys for table in package.tables):
|
|
55
|
+
source.line("from pyoq.schema import KeyKind")
|
|
56
|
+
source.line()
|
|
57
|
+
if annotations.enum_names:
|
|
58
|
+
source.lines(render_from_import(".enums", annotations.enum_names))
|
|
59
|
+
if annotations.domain_names:
|
|
60
|
+
source.lines(render_from_import(".domains", annotations.domain_names))
|
|
61
|
+
row_names = tuple(
|
|
62
|
+
name
|
|
63
|
+
for table in package.tables
|
|
64
|
+
for name in (table.row_name, *(key.type_name for key in table.keys))
|
|
65
|
+
)
|
|
66
|
+
source.lines(render_from_import(".rows", row_names))
|
|
67
|
+
write_names = tuple(
|
|
68
|
+
name for table in package.tables for name in _write_names(table)
|
|
69
|
+
)
|
|
70
|
+
source.lines(render_from_import(".writes", write_names))
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _write_names(table: GeneratedTable) -> tuple[str, ...]:
|
|
74
|
+
return (
|
|
75
|
+
table.insert_name,
|
|
76
|
+
table.update_name,
|
|
77
|
+
table.update_builder_name,
|
|
78
|
+
_returned_builder_name(table),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _returned_builder_name(table: GeneratedTable) -> str:
|
|
83
|
+
if table.required_columns:
|
|
84
|
+
return table.builder_name
|
|
85
|
+
return table.complete_builder_name
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _column_annotations(package: GeneratedPackage) -> tuple[str, ...]:
|
|
89
|
+
return tuple(
|
|
90
|
+
column.value_annotation for table in package.tables for column in table.columns
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _class_declaration(table: GeneratedTable) -> tuple[str, ...]:
|
|
95
|
+
"""Long enough table names push the base past the line limit."""
|
|
96
|
+
inline = (
|
|
97
|
+
f"class {table.class_name}(TableDescriptor["
|
|
98
|
+
f"{table.row_name}, {table.insert_name}, {table.update_name}]):"
|
|
99
|
+
)
|
|
100
|
+
if len(inline) <= 88:
|
|
101
|
+
return (inline,)
|
|
102
|
+
return (
|
|
103
|
+
f"class {table.class_name}(",
|
|
104
|
+
*render_subscript(
|
|
105
|
+
" ",
|
|
106
|
+
"TableDescriptor",
|
|
107
|
+
(table.row_name, table.insert_name, table.update_name),
|
|
108
|
+
argument_indent=" ",
|
|
109
|
+
closing_indent=" ",
|
|
110
|
+
suffix="",
|
|
111
|
+
),
|
|
112
|
+
"):",
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _render_table(source: PythonSource, table: GeneratedTable) -> None:
|
|
117
|
+
required_states = tuple("Missing" for _ in table.required_columns)
|
|
118
|
+
source.line()
|
|
119
|
+
source.line()
|
|
120
|
+
source.lines(_class_declaration(table))
|
|
121
|
+
for column in table.columns:
|
|
122
|
+
_render_column(source, table, column)
|
|
123
|
+
_render_column_tuple(source, table)
|
|
124
|
+
for key in table.keys:
|
|
125
|
+
database_name = literal(
|
|
126
|
+
key.source.name.value if key.source.name is not None else None
|
|
127
|
+
)
|
|
128
|
+
column_names = render_string_tuple(
|
|
129
|
+
tuple(column.source.name.value for column in key.columns)
|
|
130
|
+
)
|
|
131
|
+
_render_descriptor_assignment(
|
|
132
|
+
source,
|
|
133
|
+
key.constant_name,
|
|
134
|
+
"KeyDescriptor",
|
|
135
|
+
key.type_name,
|
|
136
|
+
"KeyDescriptor",
|
|
137
|
+
(
|
|
138
|
+
f"KeyKind.{key.source.kind.name}",
|
|
139
|
+
column_names,
|
|
140
|
+
database_name,
|
|
141
|
+
),
|
|
142
|
+
)
|
|
143
|
+
source.line()
|
|
144
|
+
source.line(" @staticmethod")
|
|
145
|
+
if required_states:
|
|
146
|
+
source.lines(
|
|
147
|
+
render_subscript(
|
|
148
|
+
" def builder() -> ",
|
|
149
|
+
table.builder_name,
|
|
150
|
+
required_states,
|
|
151
|
+
argument_indent=" ",
|
|
152
|
+
closing_indent=" ",
|
|
153
|
+
suffix=":",
|
|
154
|
+
)
|
|
155
|
+
)
|
|
156
|
+
else:
|
|
157
|
+
source.line(f" def builder() -> {table.complete_builder_name}:")
|
|
158
|
+
source.line(
|
|
159
|
+
f" return {table.complete_builder_name}()"
|
|
160
|
+
if not table.required_columns
|
|
161
|
+
else f" return {table.builder_name}()"
|
|
162
|
+
)
|
|
163
|
+
source.line()
|
|
164
|
+
source.line(" @staticmethod")
|
|
165
|
+
source.line(f" def update_builder() -> {table.update_builder_name}:")
|
|
166
|
+
source.line(f" return {table.update_builder_name}()")
|
|
167
|
+
source.line()
|
|
168
|
+
source.line()
|
|
169
|
+
inline = f"{table.constant_name} = {table.class_name}("
|
|
170
|
+
wrapped = len(inline) > LINE_LIMIT
|
|
171
|
+
indent = " " if wrapped else " "
|
|
172
|
+
source.lines(_constant_head(table))
|
|
173
|
+
source.line(f"{indent}{literal(table.source.name.value)},")
|
|
174
|
+
source.line(f"{indent}{literal(table.schema_name)},")
|
|
175
|
+
source.line(f"{indent}{literal(table.catalog_name)},")
|
|
176
|
+
source.line(f"{indent}{table.row_name},")
|
|
177
|
+
source.lines((" )", ")") if wrapped else (")",))
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _render_column_tuple(source: PythonSource, table: GeneratedTable) -> None:
|
|
181
|
+
"""A table has at least one column, which the schema model enforces."""
|
|
182
|
+
names = tuple(column.constant_name for column in table.columns)
|
|
183
|
+
inline = f" COLUMNS: ClassVar[tuple[object, ...]] = ({names[0]},)"
|
|
184
|
+
if len(names) == 1 and len(inline) <= LINE_LIMIT:
|
|
185
|
+
source.line(inline)
|
|
186
|
+
return
|
|
187
|
+
source.line(" COLUMNS: ClassVar[tuple[object, ...]] = (")
|
|
188
|
+
for name in names:
|
|
189
|
+
source.line(f" {name},")
|
|
190
|
+
source.line(" )")
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _render_column(
|
|
194
|
+
source: PythonSource,
|
|
195
|
+
table: GeneratedTable,
|
|
196
|
+
generated_column: GeneratedColumn,
|
|
197
|
+
) -> None:
|
|
198
|
+
_render_descriptor_assignment(
|
|
199
|
+
source,
|
|
200
|
+
generated_column.constant_name,
|
|
201
|
+
"ColumnDescriptor",
|
|
202
|
+
generated_column.value_annotation,
|
|
203
|
+
"ColumnDescriptor",
|
|
204
|
+
(
|
|
205
|
+
literal(generated_column.source.name.value),
|
|
206
|
+
f"nullable={generated_column.source.nullable!r}",
|
|
207
|
+
f"writable={generated_column.writable!r}",
|
|
208
|
+
f"has_default={generated_column.source.default is not None!r}",
|
|
209
|
+
f"generated={generated_column.source.generated is not None!r}",
|
|
210
|
+
f"scalar_family=ScalarFamily.{_scalar_family(generated_column.source.data_type.kind)}",
|
|
211
|
+
f"table_name={literal(table.source.name.value)}",
|
|
212
|
+
f"schema_name={literal(table.schema_name)}",
|
|
213
|
+
f"catalog_name={literal(table.catalog_name)}",
|
|
214
|
+
f"field_name={literal(generated_column.field_name)}",
|
|
215
|
+
f"value_type={_value_type(generated_column)}",
|
|
216
|
+
),
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def _value_type(generated_column: GeneratedColumn) -> str:
|
|
221
|
+
"""The class this column reads back as, where one class can name it.
|
|
222
|
+
|
|
223
|
+
Any JSON is a union of everything JSON can be, which is no class at all.
|
|
224
|
+
The scalar family says JSON on its own, and reading the column back asks
|
|
225
|
+
the family when the declared type names nothing.
|
|
226
|
+
"""
|
|
227
|
+
if generated_column.source.data_type.kind is TypeKind.JSON:
|
|
228
|
+
return "None"
|
|
229
|
+
return generated_column.annotation
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _scalar_family(kind: TypeKind) -> str:
|
|
233
|
+
"""The name of the family this kind holds, asked of the one authority.
|
|
234
|
+
|
|
235
|
+
Rendered rather than restated, so generated code and the code that reads
|
|
236
|
+
it back cannot disagree about what a column holds.
|
|
237
|
+
"""
|
|
238
|
+
return family_for_kind(kind).name
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _constant_head(table: GeneratedTable) -> tuple[str, ...]:
|
|
242
|
+
"""Wrap in parentheses when the name and the class will not share a line."""
|
|
243
|
+
inline = f"{table.constant_name} = {table.class_name}("
|
|
244
|
+
if len(inline) <= LINE_LIMIT:
|
|
245
|
+
return (inline,)
|
|
246
|
+
return (f"{table.constant_name} = (", f" {table.class_name}(")
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _render_descriptor_assignment(
|
|
250
|
+
source: PythonSource,
|
|
251
|
+
name: str,
|
|
252
|
+
descriptor: str,
|
|
253
|
+
parameter: str,
|
|
254
|
+
constructor: str,
|
|
255
|
+
arguments: tuple[str, ...],
|
|
256
|
+
) -> None:
|
|
257
|
+
"""Break where a formatter would break, in the order it prefers.
|
|
258
|
+
|
|
259
|
+
The value is parenthesized first and the annotation split only when even
|
|
260
|
+
that does not fit, because generated code a formatter would rewrite is
|
|
261
|
+
generated code a project cannot check.
|
|
262
|
+
"""
|
|
263
|
+
annotated = f"{descriptor}[{parameter}]"
|
|
264
|
+
declaration = f" {name}: ClassVar[{annotated}]"
|
|
265
|
+
argument_indent = " "
|
|
266
|
+
closing_lines: tuple[str, ...] = (" )",)
|
|
267
|
+
if len(f"{declaration} = {constructor}(") <= 88:
|
|
268
|
+
source.line(f"{declaration} = {constructor}(")
|
|
269
|
+
elif len(f"{declaration} = (") <= 88:
|
|
270
|
+
source.line(f"{declaration} = (")
|
|
271
|
+
source.line(f" {constructor}(")
|
|
272
|
+
argument_indent = " "
|
|
273
|
+
closing_lines = (" )", " )")
|
|
274
|
+
else:
|
|
275
|
+
source.line(f" {name}: ClassVar[")
|
|
276
|
+
source.lines(
|
|
277
|
+
render_subscript(
|
|
278
|
+
" ",
|
|
279
|
+
descriptor,
|
|
280
|
+
(parameter,),
|
|
281
|
+
argument_indent=" ",
|
|
282
|
+
closing_indent=" ",
|
|
283
|
+
suffix="",
|
|
284
|
+
)
|
|
285
|
+
)
|
|
286
|
+
source.line(f" ] = {constructor}(")
|
|
287
|
+
for argument in arguments:
|
|
288
|
+
source.line(f"{argument_indent}{argument},")
|
|
289
|
+
source.lines(closing_lines)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def _exported_names(package: GeneratedPackage) -> tuple[str, ...]:
|
|
293
|
+
return tuple(
|
|
294
|
+
name
|
|
295
|
+
for table in package.tables
|
|
296
|
+
for name in (table.class_name, table.constant_name)
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
__all__ = ("render_tables",)
|