tableio helps with quick prototyping by persisting Go structs into a database. Supports SQLite, MySQL, PostgreSQL, and MSSQL.
Create a struct with tableio tags to define field constraints:
type Person struct {
ID int64 `tableio:"pk,auto"` // Primary key, auto-increment
Name string `tableio:"unique,required"` // Unique, not null
Age int // Nullable (no tags)
Address Address // Nested struct (stored as JSON)
}pk/primarykey- Primary keyauto/autoincrement- Auto-increment (IDENTITY/SERIAL/AUTO_INCREMENT)unique- Unique constraintrequired/notnull- NOT NULL
Fields without tags default to nullable with no constraints.
The TableIO constructor NewTableIO creates a connection to your database and returns a handle to it. Use Go generics to specify your struct type:
// SQLite
peopleTable, err := NewTableIO[Person]("sqlite3", "test.db")
// MySQL
peopleTable, err := NewTableIO[Person]("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
// PostgreSQL
peopleTable, err := NewTableIO[Person]("postgres", "user=postgres password=secret host=localhost dbname=mydb sslmode=disable")
// MSSQL
peopleTable, err := NewTableIO[Person]("sqlserver", "sqlserver://sa:password@localhost:1433?database=master")The struct fields and tags determine the table structure. For the Person struct above, this SQL is generated:
CREATE TABLE IF NOT EXISTS people (
ID INT PRIMARY KEY AUTO_INCREMENT, -- or SERIAL/IDENTITY depending on DB
Name VARCHAR(255) NOT NULL UNIQUE,
Age INTEGER NULL,
Address JSON NULL -- or TEXT/NVARCHAR(MAX) depending on DB
);Table names are automatically pluralized and converted to snake_case.
Call the CreateTableIfNotExists method to create a table for your struct:
helloTable.CreateTableIfNotExists()Single row:
peopleTable.Insert(Person{
Name: "John Doe",
Age: 30,
Address: Address{City: "New York", State: "NY"},
})
// ID is auto-generated by the databaseMultiple rows:
people := []Person{
{Name: "Jane Smith", Age: 25},
{Name: "Bob Johnson", Age: 35},
}
peopleTable.InsertMany(people)people := peopleTable.All()
for _, person := range people {
fmt.Printf("ID: %d, Name: %s, Age: %d\n", person.ID, person.Name, person.Age)
}peopleTable.DeleteTableIfExists()peopleTable.Close()- Generic-based API - Type-safe operations with Go generics
- Multi-database support - SQLite, MySQL, PostgreSQL, MSSQL
- Struct tags - Define constraints with
tableio:"pk,auto,unique,required" - Auto table naming - Pluralized and snake_cased from struct name
- Auto-increment support - Database-specific syntax (IDENTITY/SERIAL/AUTO_INCREMENT)
- Nested structs - Automatically serialized to JSON/TEXT columns