DbDiff will be a set of tools for comparing database schemas. While it's still in early development, I use it daily to compare schemas across different application databases and instances. The tool exports schemas to a simple, alphabetically-sorted text format that contains just enough information to be readable and easy to compare using diff tools like WinMerge or Meld. For most of my needs, this is sufficient to verify that a database is in the correct state (yes, sometimes manual checks are necessary).
Future plans include adding a more comfortable user interface, likely built with AvaloniaUI. For now, I'm satisfied with the terminal-based tools.
Current version: 0.1.0
- Export database schemas to text format from SQL Server, PostgreSQL and SQLite
- Complete schema export including:
- Tables with full column definitions
- Views with SQL definitions and column structures
- Deterministic, diff-friendly output format
- Alphabetically sorted tables and columns for easy comparison
- Cross-database schema comparison (compare SQL Server vs PostgreSQL schemas)
- Cross-database schema comparison with SQLite limited due to the limitations of SQLite
- Automatic database type detection from connection strings
- Configurable via CLI arguments, environment variables, or configuration files
- Structured logging with Serilog
- Comprehensive security features:
- Path validation and sanitization to prevent path traversal attacks
- Protection against writing to system directories
- SQL injection prevention via parameterized queries
- Input validation throughout
- Download the latest release for your platform from the Releases page
- Extract the archive to a folder of your choice (e.g.,
C:\Tools\DbDiffon Windows or/usr/local/bin/dbdiffon Linux) - Add the folder to your system PATH environment variable to run
dbdifffrom anywhere
If you're building the tool yourself, use the provided installation script:
.\install.ps1 -Destination "C:\Tools\DbDiff"This will:
- Build and publish the project in Release mode
- Clear the destination folder (if it exists)
- Copy all files to the destination
- Optionally add the destination to your PATH
Script Parameters:
-Destination(required): Installation folder path-Configuration: Build configuration (ReleaseorDebug, default:Release)-SkipBuild: Skip building and use existing publish folder
Examples:
# Install to a custom location
.\install.ps1 -Destination "C:\Tools\DbDiff"
# Install Debug build
.\install.ps1 -Destination "C:\Tools\DbDiff" -Configuration Debug
# Install without rebuilding (use existing publish folder)
.\install.ps1 -Destination "C:\Tools\DbDiff" -SkipBuildUse the uninstall script to remove DbDiff:
.\uninstall.ps1 -InstallPath "C:\Tools\DbDiff"This will:
- Remove the installation folder and all its contents
- Remove the path from your PATH environment variable (if present)
dotnet buildcd src/DbDiff.Cli
dotnet run -- --connection "Your-Connection-String" --output schema.txtOr build and run the published executable:
dotnet publish -c Release
cd src/DbDiff.Cli/bin/Release/net10.0/publish
./DbDiff.Cli --connection "Your-Connection-String"SQL Server:
dbdiff --connection "Server=localhost;Database=MyDb;Trusted_Connection=true;" --output schema.txtPostgreSQL:
dbdiff --connection "Host=localhost;Database=mydb;Username=user;Password=pass" --output schema.txt-c, --connection <string>: Database connection string (required)-o, --output <path>: Output file path (default: schema.txt)-d, --database-type <type>: Database type:sqlserver,postgresql(auto-detected if not specified)--config <path>: Path to configuration file (default: appsettings.json)--ignore-position: Exclude column ordinal positions from output--exclude-view-definitions: Exclude view SQL definitions from output (column structure still included)-h, --help: Show help information
DbDiff can automatically detect the database type from your connection string:
- SQL Server keywords:
Server=,Data Source=,Initial Catalog=,Integrated Security= - PostgreSQL keywords:
Host=,Username=
You can override auto-detection using the --database-type parameter.
Connection strings and output paths can be configured in multiple ways (priority order):
- Command-line arguments (highest priority)
- Environment variables
DBDIFF_ConnectionStrings__DefaultDBDIFF_Export__OutputPath
- Configuration file (
appsettings.json)
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=MyDb;Trusted_Connection=true;"
},
"Export": {
"OutputPath": "schema.txt"
},
"Serilog": {
"LogPath": "logs/dbdiff-.txt",
"RollingInterval": "Day",
"RetainedFileCountLimit": 7
}
}The tool exports database schemas in a custom text format optimized for diff tools:
DATABASE: MyDatabase
EXTRACTED: 2025-12-16T12:00:00.000Z
TABLE: dbo.Users
COLUMN: Email
OrdinalPosition: 3
Type: nvarchar
Nullable: No
MaxLength: 255
COLUMN: Id
OrdinalPosition: 1
Type: int
Nullable: No
COLUMN: Name
OrdinalPosition: 2
Type: nvarchar
Nullable: Yes
MaxLength: 100
VIEW: dbo.ActiveUsers
DEFINITION:
CREATE VIEW dbo.ActiveUsers AS
SELECT Id, Name, Email
FROM dbo.Users
WHERE IsActive = 1
COLUMN: Email
OrdinalPosition: 3
Type: nvarchar
Nullable: Yes
MaxLength: 255
COLUMN: Id
OrdinalPosition: 1
Type: int
Nullable: No
COLUMN: Name
OrdinalPosition: 2
Type: nvarchar
Nullable: Yes
MaxLength: 100
Features:
- Tables, views, and columns are alphabetically sorted
- Views include complete SQL definitions for comparison
- Consistent formatting and indentation
- One property per line
- Deterministic output for reliable diffing
The project follows Hexagonal Architecture (Ports & Adapters) with clear separation of concerns:
┌─────────────┐
│ DbDiff.Cli │ ──► Entry point, CLI argument parsing
└──────┬──────┘
│
┌──────▼───────────────┐
│ DbDiff.Application │ ──► Use cases, DTOs, Formatters
└──────┬───────────────┘
│
┌──────▼────────────┐ ┌──────────────────────┐
│ DbDiff.Domain │ ◄───── │ DbDiff.Infrastructure│
│ (Port Interfaces)│ │ (Adapters: MSSQL) │
└───────────────────┘ └──────────────────────┘
- DbDiff.Domain: Core domain entities and port interfaces (no dependencies)
- DbDiff.Application: Application services, DTOs, and formatters
- DbDiff.Infrastructure: Database-specific implementations (MSSQL)
- DbDiff.Cli: Console application entry point
- ✅ Microsoft SQL Server (MSSQL)
- ✅ PostgreSQL
- ✅ SQLite
DbDiff uses a consistent output format for all database types, making it possible to compare schemas across different database platforms:
# Export SQL Server schema
dbdiff --connection "Server=localhost;Database=MyDb;Trusted_Connection=true;" --output sqlserver-schema.txt
# Export PostgreSQL schema
dbdiff --connection "Host=localhost;Database=mydb;Username=user;Password=pass" --output postgres-schema.txt
# Exort SQLite schema
DbDiff.Cli --connection "Data Source=path-to-file/database.db" --database-type sqlite --output sqlite-schema.txt
# Compare using your favorite diff tool
diff sqlserver-schema.txt postgres-schema.txt
diff sqlserver-schema.txt sqlite-schema.txtNote: Data types will differ between platforms (e.g., SQL Server's nvarchar vs PostgreSQL's character varying), but the consistent format allows you to easily identify structural differences.
- .NET 10.0 SDK or later
- SQL Server (for SQL Server support)
- PostgreSQL (for PostgreSQL support)
- SQLite datbase file
- Microsoft.Data.SqlClient: SQL Server connectivity
- Microsoft.Data.SqLite: SQLite connectivity
- Npgsql: PostgreSQL connectivity
- Serilog: Structured logging
- Microsoft.Extensions.*: Configuration and dependency injection
dotnet testThis project includes automated workflows for continuous integration and releases:
The CI workflow runs automatically on every push or pull request to main or develop branches:
- Restores dependencies
- Builds the project in Release mode
- Runs all tests
- Uploads build artifacts
Pull requests trigger multi-platform testing on:
- Ubuntu (Linux)
- Windows
- macOS
This ensures compatibility across all supported platforms.
To create a release:
- Update the version in
CHANGELOG.mdfollowing semantic versioning - Commit your changes
- Create and push a version tag:
git tag v1.0.0
git push origin v1.0.0The release workflow automatically:
- Builds self-contained executables for:
- Windows x64
- Linux x64
- macOS x64 (Intel)
- macOS ARM64 (Apple Silicon)
- Creates release archives (ZIP for Windows, tar.gz for Linux/macOS)
- Creates a GitHub release with all binaries attached
- Links to the CHANGELOG for release notes
Note: GitHub Actions requires appropriate permissions. Ensure your repository settings allow Actions to create releases.
Logs are written to the logs/ directory by default. The log file path and retention policy can be configured in appsettings.json:
{
"Serilog": {
"LogPath": "logs/dbdiff-.txt",
"RollingInterval": "Day",
"RetainedFileCountLimit": 7
}
}See CHANGELOG.md for version history and planned features.
- Schema comparison (diff) functionality
- Support for additional database objects (indexes, foreign keys, stored procedures, functions, triggers, etc.)
- GUI application using AvaloniaUI
- Multiple output formats (JSON, YAML, SQL DDL)
- Support for additional databases (MySQL, Oracle, etc.)
DbDiff takes security seriously. We've implemented comprehensive security measures including:
- Path validation: All file paths are validated and sanitized to prevent path traversal attacks
- SQL injection prevention: All database queries use parameterized statements
- Input validation: Comprehensive validation of all user inputs
For detailed security information, please see SECURITY.md.
If you discover a security vulnerability, please report it responsibly by contacting the maintainers directly rather than creating a public issue.
Contributions are welcome! Please follow the existing code structure and architectural principles.
By contributing to this project, you agree that your contributions will be licensed under the MIT License.
This project is licensed under the MIT License - see the LICENSE.md file for details.
- ✅ Commercial use allowed
- ✅ Modification allowed
- ✅ Distribution allowed
- ✅ Private use allowed
- ❗ License and copyright notice must be included