Library · Data Practice OS
Naming conventions
Reference guide · Published · Source reviewed
Names are how people and agents find data. An agent that reads the catalog cannot ask what GEN_RAW_20260630 was for. The rule that matters most is that each part of a fully qualified name has one job, and no part repeats another.
Source and status. These conventions come from a platform team's Snowflake platform work: Snowflake technical details §3 Naming conventions, Options paper: Snowflake database and schema layout and Options paper: pipeline transformation code, Oct 2026, in the platform docs. All of them are proposed. The platform team has not agreed them. They are the best worked example in most organisations, so the practice adopts their rules as its default and treats the platform team names as an example.
General rules
- Uppercase in Snowflake. Lowercase in Unity Catalog and in dbt file names. The engine shows the case it uses.
- Use letters, digits and underscores only. No spaces, no version numbers unless they are needed, and no private abbreviations.
- Keep names short but clear. A name describes its content, never its history.
- A schema name must not suggest a different kind of object from the one it holds. In that platform team's work,
STGheld staging models, stages, UDFs and Streamlit apps all at once. The proposal moves stages to the raw schemas, apps toSTRMLITand functions to a functions schema, so thatSTGholds staging models only. - No backup copies inside a raw or model schema (for example
GEN_RAW_20260630). Use a batch ID, Time Travel or a Zero-copy clone instead.
The three parts
| Part | Job | Snowflake pattern | Example | Databricks equivalent |
|---|---|---|---|---|
| Database / catalog | The data stage: raw, or one environment | <ORG>_RAW_DB, <ORG>_<ENV>_DB |
ORG_RAW_DB, ORG_DEV_DB |
Catalogs raw, dev, test, prod (or <org>_raw, <org>_<env>) |
| Schema | The source system (raw) or the layer (models) | Raw: <SOURCE>. Models: SRC, STG, INT, DW |
ORG_RAW_DB.GEN, ORG_DEV_DB.STG |
raw.gen, dev.stg |
| Table | The entity | Raw: the source table name, unchanged. Models: see below | ORG_RAW_DB.GEN.DOBJ |
raw.gen.dobj |
Why one raw database? Raw data is a source snapshot, not environment data. Each source is loaded once per account, written only by a loader role, and every environment reads it. An environment can then be rebuilt without touching raw data (Raw replay copy). The exception is data that each environment makes (for example app logs). That data gets one raw schema per source environment, <SOURCE>_<ENV> in nonprod and <SOURCE> in prod, and prod data stays in prod.
Layers and model names
The practice's Medallion architecture language maps onto the platform team layer names like this. The platform team names were kept because four of six repos already used them. The rules come from dbt Labs and GitLab.
| Medallion | Schema | Model name | Rule |
|---|---|---|---|
| Bronze | RAW (in the raw database, one schema per source) |
Source table name | Loaded as delivered, plus load columns BATCH_ID, SOURCE_FILE, LOADED_AT |
| Bronze → silver | SRC |
src_<source>_<entity> |
One model per raw table. List and cast every column. No SELECT *, joins or filters. Only this layer reads raw |
| Silver | STG |
stg_<source>_<entity> |
Clean and conform. Business logic in hand-written SQL, not macros |
| Silver | INT |
int_<source>_<entity> |
Combine and compute. Complex logic lives here so it can be tested |
| History | SCD (optional) |
scd_<source>_<entity> |
Slowly changing history of a source |
| Gold | DW |
<source>_<entity> (no layer prefix) |
Consumer-facing data products with contracts and tests |
| Pipeline state | ADMIN |
<SOURCE>_<THING>_CHECKPOINT |
Checkpoints and run logs, not source data |
dbt folders follow the layers (source/, stage/, intermediate/, semantic/). dbt Labs explicitly allows its own layer names to be changed if the team states the change and the reason. Use a custom generate_schema_name macro so that no code hard-codes an environment database name. The platform team found at least four hard-coded ORG_DEV_DB references.
Stages, integrations and files
| Object | Pattern | Example |
|---|---|---|
| Landing stage | <SOURCE>_LANDING in the raw schema |
ORG_RAW_DB.GEN.GEN_LANDING |
| Storage integration | One per bucket. Read-only for landing | <ORG>_<BUCKET>_INT |
| S3 path (the organisation code writes) | s3://<bucket>/<source>/<batch_id or version>/ |
s3://…/legislation/2026-10-30/ |
| S3 path (manual export) | s3://<bucket>/<source>/, with the load setting the batch ID |
s3://…/gen/ |
Roles
Name a role for what it does, not who uses it.
| Role | Can do |
|---|---|
RAW_LOADER_ROLE |
Insert into raw tables and read landing stages. Cannot create, replace or drop a table |
RAW_OWNER_ROLE |
Create and alter raw tables after a reviewed schema change. The table's owner is the only role that can drop it |
<ENV>_ETL_ROLE |
Read raw; write the environment database (dbt) |
<ENV>_READER_ROLE |
Read DW in one environment (apps, BI, graph loads, agents) |
INFRA_DEPLOY_ROLE |
Create databases, schemas, roles and stages, used by the infrastructure CI only |
ACCOUNT_VIEWER_ROLE |
See every object, grant and policy, but no table data. For audits and discovery |
ACCOUNT_DATA_VIEWER_ROLE |
The viewer role plus SELECT, with masking still applied. Time-boxed, with approval |
Snowflake has no read-only ACCOUNTADMIN. The viewer roles fill that gap using the SNOWFLAKE database roles (OBJECT_VIEWER, USAGE_VIEWER, GOVERNANCE_VIEWER, SECURITY_VIEWER). Do not grant USAGE on procedures, because an owner's-rights procedure can write. In Unity Catalog, use groups named the same way and grant them at catalog or schema level.
Tags
| Tag | Values | Set on |
|---|---|---|
DATA_CLASSIFICATION |
OFFICIAL, SENSITIVE, PROTECTED (or your scheme's levels) |
Each raw schema, then columns |
CLASSIFICATION_STATUS |
ASSUMED (the source page's handling level), CONFIRMED (formal classification) |
Same |
Masking policies attach to column tags, not schema tags. See Governance, security and trust.
Not when
- Do not rename working repos just to match. The platform team's migration plan renames only when a repo moves to its new home.
- Do not invent a new layer per domain (for example
GEN_DW). Schemas per domain multiplied by layers multiply grants. Use shared layer schemas and put the source in the model name.
Related: Medallion layers and modelling, Pipeline code - explicit vs metadata-driven, Infrastructure as code for the data platform.
Source links: Data Practice reading list.