Schema Adaptation¶
Schema adaptation is the step that makes the tool general: given a database it has never seen, it decides what each table represents and how its columns should be populated. This chapter describes how that inference works and, just as important, where it is fallible.
Reflection first¶
Adaptation starts from facts, not guesses. Through SQLAlchemy’s inspector the analyzer reads the concrete structure of the database: tables, columns and their types, primary keys, and foreign-key constraints. None of this is inferred; it is read directly from the schema. Everything the tool decides is built on top of this factual layer.
Entity classification¶
On top of structure, the analyzer assigns each table an entity type (user,
customer, product, order, review, category, and a handful of others, with
unknown as the explicit fallback). Classification scores the table’s name
against sets of patterns associated with each type and takes the best match.
This is a heuristic, and heuristics have edges. The design accepts that classification will sometimes be wrong and makes wrongness cheap through the The Fallback Ladder and through generated code you can edit. It does not pretend the classifier is authoritative.
A worked limitation¶
A concrete example of the edge, preserved because it is instructive: substring
matching does not always align with human intuition about word membership. A
table named categories is not matched by the pattern category, because
categories decomposes as categori + es, and category is not a
substring of it. The result is that a plainly-named table can land in the
unknown bucket.
This is documented rather than papered over for a reason. It is exactly the kind
of case where the ladder earns its place: an unknown table still generates,
one rung lower, from its column names and types. The classifier being imperfect
is survivable by design.
Relationship and rule detection¶
Two further inferences ride on the structural layer:
Relationships. Foreign keys are turned into explicit relationships, which the Generator Factory uses to order table generation so that referenced rows exist before the rows that reference them.
Business rules. Recurring structural shapes become candidate rules: a non-null unique
email, a numeric column that is always positive. These are reported with a confidence and inform generation where they apply.
Known fidelity gaps¶
A few limits are worth stating so they are not mistaken for bugs:
Loosely typed columns with non-obvious names. A column whose name signals a date or timestamp (
created_at,*_date) is generated as a date even when it is declaredTEXT. A loosely typed column whose name gives no such signal is generated from its declared type, so aTEXTcolumn holding, say, encoded JSON becomes text. Correcting it is a one-line edit in the generated code.Arbitrary unique and composite constraints. Uniqueness is enforced for well-known columns such as
email, and primary keys are generated as contiguous sequential integers across every template. General unique constraints and composite keys are not yet enforced during generation.
These are on the roadmap under constraint fidelity, and they are the kind of gap the “generated code is the product” principle is designed to make trivial to close in the meantime. The post-generation constraint check (see Architecture) reports any that a given dataset violates.