Database-first scaffolding
Generate a schema manifest and annotated C# classes from an existing PostgreSQL database.
Overview
The library is code-first by default: you annotate C# classes and the generator produces the data layer and migrations. For an existing database, the CLI tool can work in the other direction — reading a live schema and scaffolding it back into the same model the analyzer understands.
NEW in 0.3.3
Two sub-commands of the migration tool cover this:
| Command | Input | Output |
|---|---|---|
scaffold schema |
A live PostgreSQL connection | A structure.json schema manifest |
scaffold classes |
A live connection or a structure.json |
Annotated [Table] C# classes |
Both reuse the same schema model and SQL generator as the code-first pipeline, so the result round-trips: scaffolded classes, recompiled and run back through generate, reproduce the same schema.
scaffold schema
Read a database and write a structure.json:
socigydb scaffold schema \
--connection "Host=localhost;Username=postgres;Password=...;Database=app" \
--schema public \
--output ./structure.json| Option | Description |
|---|---|
--connection |
PostgreSQL connection string (required) |
--schema |
Database schema to read (default public) |
--output |
Output path (default ./structure.json) |
scaffold classes
Generate annotated C# classes, either directly from a database or from a previously-written structure.json:
# From a live database
socigydb scaffold classes \
--connection "Host=localhost;Username=postgres;Password=...;Database=app" \
--output ./Models \
--namespace MyApp.Data
# From an existing schema manifest
socigydb scaffold classes \
--from-schema ./structure.json \
--output ./Models \
--namespace MyApp.Data| Option | Description |
|---|---|
--connection |
PostgreSQL connection string (omit when using --from-schema) |
--from-schema |
Read from an existing structure.json instead of a live database |
--schema |
Database schema to read (default public) |
--output |
Output directory for the generated classes (required) |
--namespace |
Namespace for the generated classes (default: derived from the output directory) |
One {ClassName}.cs file is written per table.
What is recovered
The reader maps PostgreSQL metadata back to the attributes the analyzer reads, including:
- Tables and columns, with CLR types inferred from the SQL types.
- Primary keys (
[PrimaryKey]) and auto-increment / identity columns ([AutoIncrement]). NOT NULL→ non-nullable C# types; nullable columns →T?.varchar(n)length →[StringLength(n)].- Recognized defaults mapped back to their
DbDefaultstoken — for examplegen_random_uuid()→[Default(DbDefaults.Guid.Random)],timezone('utc', now())→[Default(DbDefaults.Time.Now)]. Unrecognized defaults are preserved verbatim. jsonbcolumns →[RawJsonColumn].- Foreign keys →
[ForeignKey(typeof(Target), Keys = [...], TargetKeys = [...])], including theON DELETEaction. - A
[Column("…")]override is emitted only when the database column name does not match the default snake_case of the property, keeping the output clean.
Limitations
Some information cannot be reconstructed from the database alone and is scaffolded conservatively:
[Encrypted]columns are stored asbytea, indistinguishable from a genuinebyte[]column. They scaffold asbyte[]; re-apply[Encrypted]by hand where appropriate.- Enum-backed columns scaffold as their underlying primitive.
CHECKconstraints and database enum types are not yet scaffolded.
Treat scaffolding as a starting point: review the generated classes, then continue code-first from there.