Files
pgsql-jellyfin/docs/DATABASE_SCHEMA_CREATION.md
T
wjones a3eb4b1b57 Add automatic PostgreSQL database creation and migration
- Added Jellyfin.Database.Providers.Postgres project with full EF Core migration support for PostgreSQL.
- Implemented automatic database creation and privilege assignment on startup.
- Generated initial migration and model snapshot for PostgreSQL schema.
- Updated build, test, and dependency files to include PostgreSQL provider and Npgsql packages.
- Added PowerShell script for generating and testing PostgreSQL migrations.
- No changes to application logic outside database provider/migration infrastructure.
2026-02-22 18:51:24 -05:00

255 lines
7.5 KiB
Markdown

# Database Schema Creation - How It Works
## Yes! The Database Schema is Created Automatically
Jellyfin has a sophisticated migration system that **automatically creates all database tables** when you first run it with a new database provider.
## How It Works
### 1. **First-Time Initialization** (New Installation)
When Jellyfin starts for the first time:
```csharp
// From JellyfinMigrationService.cs lines 113-118
var databaseCreator = dbContext.Database.GetService<IDatabaseCreator>() as IRelationalDatabaseCreator;
if (!await databaseCreator.ExistsAsync().ConfigureAwait(false))
{
await databaseCreator.CreateAsync().ConfigureAwait(false);
}
```
**What happens:**
1. Checks if database exists
2. If not, **creates the database**
3. Creates the `__EFMigrationsHistory` table to track applied migrations
4. Seeds initial migration records
### 2. **Migration Application**
The `JellyfinMigrationService` manages two types of migrations:
#### A. **Database Migrations** (EF Core Schema Migrations)
These create the actual tables, columns, indexes, and constraints.
**SQLite**: Has 75+ migration files (as of current version)
- Located in: `src\Jellyfin.Database\Jellyfin.Database.Providers.Sqlite\Migrations\`
- Examples:
- `20200514181226_AddActivityLog.cs`
- `20200613202153_AddUsers.cs`
- `20241020103111_LibraryDbMigration.cs`
**PostgreSQL**: Currently has **NO migration files yet** ⚠️
#### B. **Code Migrations** (Data Migrations)
These handle data transformations and post-schema setup tasks.
```csharp
// From JellyfinMigrationService.cs lines 459-460
var migrator = _jellyfinDbContext.GetService<IMigrator>();
await migrator.MigrateAsync(_databaseMigrationInfo.Key).ConfigureAwait(false);
```
### 3. **Migration Stages**
Migrations run in specific stages during startup:
```csharp
public enum JellyfinMigrationStageTypes
{
PreStartup,
CoreInitialisation, // <- Database schema created here
PostStartup
}
```
**CoreInitialisation Stage** is where:
- EF Core migrations are applied
- Database schema (tables) is created
- Indexes and constraints are added
## Current PostgreSQL Status
### ⚠️ **Important**: PostgreSQL Migrations Need to Be Generated
The PostgreSQL provider is **missing EF Core migration files**. This means:
**What's Missing:**
- No `.cs` migration files in `src\Jellyfin.Database\Jellyfin.Database.Providers.Postgres\Migrations\`
- Schema won't be created automatically for PostgreSQL
- First run will fail or create empty database
**What Exists:**
- `PostgresDesignTimeJellyfinDbFactory.cs` - Design-time factory for generating migrations
- PostgreSQL provider implementation
- Connection and configuration code
### How to Generate PostgreSQL Migrations
You need to generate the initial migration that creates all tables:
```bash
# Navigate to the PostgreSQL provider project
cd src\Jellyfin.Database\Jellyfin.Database.Providers.Postgres
# Generate initial migration (creates all tables)
dotnet ef migrations add InitialCreate --context JellyfinDbContext --output-dir Migrations
# Or, copy and adapt migrations from SQLite provider
# This is more complex but ensures parity with SQLite schema
```
### Alternative: Runtime Schema Creation (Development Only)
For development/testing, you could modify the code to use `EnsureCreated()`:
```csharp
// WARNING: Only for development - bypasses migration system
await dbContext.Database.EnsureCreatedAsync().ConfigureAwait(false);
```
⚠️ **Don't use in production** - this bypasses the migration history system.
## What Gets Created
When migrations run properly, they create these tables:
### Core Tables (from JellyfinDbContext.cs)
- **Users** - User accounts
- **Permissions** - User permissions
- **Preferences** - User preferences
- **AccessSchedules** - Access time restrictions
- **ActivityLogs** - Activity/audit logs
- **ApiKeys** - API authentication keys
- **Devices** - Client devices
- **DeviceOptions** - Device-specific settings
- **DisplayPreferences** - UI display settings
- **ItemDisplayPreferences** - Item-specific display settings
- **CustomItemDisplayPreferences** - Custom item preferences
- **ImageInfos** - Image metadata
- **TrickplayInfos** - Video preview thumbnails metadata
- **MediaSegments** - Video chapter/intro/credits data
### Library Tables (from BaseItemRepository)
- **BaseItems** - Media library items (movies, shows, etc.)
- **AncestorIds** - Item hierarchy relationships
- **AttachmentStreamInfos** - Subtitle/attachment metadata
- **Chapters** - Video chapter information
- **ItemValues** - Genre/Studio/Artist tags
- **ItemValuesMap** - Tag-to-item relationships
- **MediaStreamInfos** - Audio/video stream metadata
- **UserData** - Watch history, ratings, favorites
### System Tables
- **__EFMigrationsHistory** - Tracks applied migrations
## Verifying Schema Creation
### After Jellyfin Starts Successfully
**SQLite:**
```bash
sqlite3 data/jellyfin.db ".tables"
```
**PostgreSQL:**
```bash
psql -U jellyfin -d jellyfin -c "\dt"
```
You should see all the tables listed above.
### Checking Migration History
**PostgreSQL:**
```sql
SELECT * FROM "__EFMigrationsHistory" ORDER BY "MigrationId";
```
This shows which migrations have been applied.
## Troubleshooting
### Error: "Table does not exist"
**Cause:** Migrations haven't been applied
**Solution:**
1. Check logs for migration errors
2. Verify database connection
3. Ensure migrations exist in the provider assembly
4. Manually run: `dotnet ef database update`
### PostgreSQL: No Tables Created
**Cause:** PostgreSQL provider has no migration files
**Solution:** Generate migrations:
```bash
cd src\Jellyfin.Database\Jellyfin.Database.Providers.Postgres
dotnet ef migrations add InitialCreate --context JellyfinDbContext
```
### Migration Fails
**Cause:** Database permissions, connection issues, or corrupt migration
**Solution:**
1. Check database user has CREATE TABLE permissions
2. Verify connection string
3. Check logs: `<config-dir>/logs/`
4. Restore from backup if available
## Best Practices
### For Development
1. **Keep migrations in sync** between providers
2. **Test migrations** before deploying
3. **Backup database** before applying migrations
4. **Use source control** for migration files
### For Production
1. **Never use EnsureCreated()** - always use migrations
2. **Backup before upgrades** that include migrations
3. **Test migrations** in staging environment first
4. **Monitor logs** during first startup with new database
### For Contributors
If adding new tables/columns:
1. **Update `JellyfinDbContext`** with new DbSets
2. **Generate migrations** for ALL providers (SQLite, PostgreSQL)
3. **Test migration** on clean database
4. **Include migration** in pull request
## Migration Workflow
```
Startup → Check Database Exists → Create if Missing
Load Migration History
Find Pending Migrations (compare applied vs available)
Apply Each Migration in Order:
- Database Migrations (schema changes)
- Code Migrations (data transformations)
Update Migration History
Continue Jellyfin Startup
```
## Summary
**Question:** Is there code to create the database and tables?
**Answer:** **YES!**
- ✅ Database creation: Automatic via `IDatabaseCreator`
- ✅ Table schema: Via EF Core migrations
- ✅ Migration tracking: Via `__EFMigrationsHistory`
- ✅ Automatic application: Via `JellyfinMigrationService`
- ⚠️ PostgreSQL: **Requires migration files to be generated first**
The system is fully automatic **once migrations exist** for your database provider. SQLite is ready to go. PostgreSQL needs its migrations generated using the `dotnet ef migrations add` command.