Skip to main content

writing-database-queries

Bitwarden database architecture, migrations, and dual-ORM strategy. Use when working with `.sql` files, stored procedures, EF migrations, or database schema changes. Also use when deciding whether a change needs both Dapper and EF Core implementations, or whether a breaking stored-procedure change requires `_V2` versioning.

来源信息

仓库
bitwarden/server
最近来源活动
2026年4月21日 13:42
检测到的 SKILL.md 语言
英语
星标
20,341
分支
1,797

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
writing-database-queries
description
Bitwarden database architecture, migrations, and dual-ORM strategy. Use when working with `.sql` files, stored procedures, EF migrations, or database schema changes. Also use when deciding whether a change needs both Dapper and EF Core implementations, or whether a breaking stored-procedure change requires `_V2` versioning.
## Dual-ORM Architecture Bitwarden maintains two data access implementations, split by database provider: - **MSSQL:** Dapper with stored procedures - **PostgreSQL, MySQL, SQLite:** Entity Framework Core These implementations are **mutually exclusive at runtime** — SQL Server uses only Dapper, while the other providers use only EF Core. Both implementations conform to the same repository interfaces. - When **adding new repository functionality**, implement it in **both** Dapper and EF Core (unless the feature is explicitly EF-only). - When **modifying an existing stored procedure** in a backwards-compatible way (for example, adding a new parameter with a default), **EF Core changes are not required**. - Some commercial features (for example, **Secrets Manager**) are **EF Core only**. ## Evolutionary Database Design (EDD) Bitwarden Cloud uses a **no-rollback** approach to database deployments. The key implication: **server deployments can be rolled back, but database migrations cannot**, so migrations must be designed to avoid being a source of downtime. All MSSQL migrations live in `util/Migrator/DbScripts/` and execute in chronological order based on the migration filename (`YYYY-MM-DD_##_Description.sql`). > Note: You may see `util/Migrator/DbScripts_transition/` and `util/Migrator/DbScripts_finalization/` folders. These are not currently used; ignore them for now. Simple additive changes (new nullable column, new table, new stored procedure) typically require only a single migration script in `util/Migrator/DbScripts/`. ### Stored procedure compatibility Stored procedure changes fall into two categories: - **Non-breaking (DEFAULT parameters):** Adding a parameter with a default value (e.g., `@NewParam BIT = NULL`) is backwards-compatible. Existing callers keep working; no `_V2` is needed. - **Breaking (`_V2` versioning):** Required when result-set structure changes, calling patterns change (e.g., single result → multiple result sets), required parameters are added without defaults, or query semantics differ. Implement this by creating `ProcedureName_V2` while retaining the original procedure for backwards compatibility. Table-level breaking changes (removing columns, changing types) typically cascade into stored procedure changes and often require the `_V2` pattern. **Always defer to the developer on migration strategy.** The approach is complex and context-dependent. When a database change is needed, write the migration script and ask the developer whether `_V2` versioning or additional steps are required. ## Key locations - `src/Sql/dbo` — Master schema source of truth - `util/Migrator/DbScripts` — All migrations (single folder, chronological) ## ORM-Specific Implementation When implementing Dapper repository methods, stored procedures, or MSSQL migration scripts, activate the `implementing-dapper-queries` skill. When implementing EF Core repositories, generating EF migrations, or working with PostgreSQL/MySQL/SQLite, activate the `implementing-ef-core` skill. ## Critical Rules These are the most frequently violated conventions. Claude cannot fetch the linked docs at runtime, so these are inlined here: - **Migration file naming:** `YYYY-MM-DD_##_Description.sql` (e.g., `2025-06-15_00_AddVaultColumn.sql`) - **All schema objects use `dbo` schema** — never create objects in other schemas - **Constraint naming:** `PK_TableName` (primary key), `FK_Child_Parent` (foreign key), `IX_Table_Column` (index), `DF_Table_Column` (default) - **Idempotent scripts:** Use `IF NOT EXISTS` / `IF COL_LENGTH(...)` guards before schema changes in migration scripts - **New repository functionality requires both Dapper and EF Core implementations** — unless the feature is explicitly EF-only or the change is a backwards-compatible stored procedure modification - **Integration tests use `[DatabaseData]` attribute** — this runs the test against all configured database providers ## Further Reading - [SQL code style](https://contributing.bitwarden.com/contributing/code-style/sql/) - [Database migrations (MSSQL)](https://contributing.bitwarden.com/contributing/database-migrations/mssql) - [Database migrations (EF)](https://contributing.bitwarden.com/contributing/database-migrations/ef) - [Evolutionary Database Design](https://contributing.bitwarden.com/contributing/database-migrations/edd)
在 GitHub 查看