Skip to content

Commit d66311a

Browse files
psaikaushiksd-db
andauthored
fix: enforce 255-character identifier length limit for Databricks relations (#1391)
## Summary Enforces the 255-character identifier length limit for Databricks relations at relation creation time, preventing a cryptic runtime `DatabricksExecutionError` when `store_failures` generates overly-long table names. Closes #1309 ## Problem When `store_failures: true` is enabled, dbt generates table names by concatenating the test name, model name, and arguments. For deep schema tests with verbose names, this can exceed Databricks' 255-character limit for table names, causing: ``` [RequestId=...] Invalid input: RPC CreateStagingTable Field managedcatalog.StagingTableInfo.name: name "accepted_map_keys_stg_product_search_create_sizes__relax__..." too long. Maximum length is 255 characters. ``` This error is unhelpful — it doesn't explain what the 255-character limit is, which test/model caused it, or how to fix it. ## Fix Added `relation_max_name_length()` and `__post_init__` validation to `DatabricksRelation`, following the exact same pattern used by the [Postgres adapter](https://github.com/dbt-labs/dbt-adapters/blob/main/dbt-postgres/src/dbt/adapters/postgres/relation.py): ```python MAX_CHARACTERS_IN_IDENTIFIER = 255 def relation_max_name_length(self): return MAX_CHARACTERS_IN_IDENTIFIER def __post_init__(self): if ( self.identifier is not None and self.type is not None and len(self.identifier) > self.relation_max_name_length() ): raise DbtRuntimeError( f"Relation name '{self.identifier}' " f"is longer than {self.relation_max_name_length()} characters. ..." ) ``` **Before:** ``` [RequestId=...] Invalid input: RPC CreateStagingTable ... name "accepted_map_keys_stg_..." too long. ``` **After:** ``` Relation name 'accepted_map_keys_stg_product_search_create_sizes__...' is longer than 255 characters. Databricks has a maximum identifier length of 255 characters. If this is a store_failures table, consider using a shorter test name or setting a custom alias. ``` ## Checklist - [x] Follows the same pattern as the Postgres adapter - [x] Catches the error at relation creation time, not at SQL execution - [x] Error message includes actionable guidance --------- Co-authored-by: Shubham Dhal <shubham.dhal@databricks.com>
1 parent b082730 commit d66311a

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## dbt-databricks 1.11.8 (TBD)
2+
3+
### Fixes
4+
5+
- Validate relation identifier length at creation time and raise a clear error when it exceeds Databricks' 255-character limit ([#1309](https://github.com/databricks/dbt-databricks/issues/1309))
6+
17
## dbt-databricks 1.11.7 (Apr 17, 2026)
28

39
### Features

dbt/adapters/databricks/relation.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from dbt.adapters.databricks.utils import remove_undefined
1818

1919
KEY_TABLE_PROVIDER = "Provider"
20+
MAX_CHARACTERS_IN_IDENTIFIER = 255
2021

2122

2223
@dataclass
@@ -86,6 +87,19 @@ class DatabricksRelation(BaseRelation):
8687
databricks_table_type: Optional[DatabricksTableType] = None
8788
temporary: Optional[bool] = False
8889

90+
def __post_init__(self) -> None:
91+
if self.identifier and self.type:
92+
if len(self.identifier) > self.relation_max_name_length():
93+
raise DbtRuntimeError(
94+
f"Databricks has a maximum identifier length of "
95+
f"{self.relation_max_name_length()} characters. "
96+
"Use a shorter name or configure a custom alias."
97+
)
98+
99+
@classmethod
100+
def relation_max_name_length(cls) -> int:
101+
return MAX_CHARACTERS_IN_IDENTIFIER
102+
89103
@classmethod
90104
def __pre_deserialize__(cls, data: dict[Any, Any]) -> dict[Any, Any]:
91105
data = super().__pre_deserialize__(data)

tests/unit/test_relation.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22
from dbt_common.contracts.constraints import ConstraintType
3+
from dbt_common.exceptions import DbtRuntimeError
34

45
from dbt.adapters.databricks import relation
56
from dbt.adapters.databricks.constraints import (
@@ -8,6 +9,7 @@
89
PrimaryKeyConstraint,
910
)
1011
from dbt.adapters.databricks.relation import (
12+
MAX_CHARACTERS_IN_IDENTIFIER,
1113
DatabricksQuotePolicy,
1214
DatabricksRelation,
1315
DatabricksRelationType,
@@ -370,6 +372,27 @@ def test_render_constraints_for_create__with_constraints(
370372
assert relation.render_constraints_for_create() == "a > 1, PRIMARY KEY (a)"
371373

372374

375+
class TestIdentifierLengthValidation:
376+
def test_valid_identifier_length(self):
377+
identifier = "a" * MAX_CHARACTERS_IN_IDENTIFIER
378+
rel = DatabricksRelation.create(identifier=identifier, type="table")
379+
assert rel.identifier == identifier
380+
381+
def test_identifier_too_long_raises(self):
382+
identifier = "a" * (MAX_CHARACTERS_IN_IDENTIFIER + 1)
383+
with pytest.raises(DbtRuntimeError, match="maximum identifier length of 255 characters"):
384+
DatabricksRelation.create(identifier=identifier, type="table")
385+
386+
def test_long_identifier_without_type_is_allowed(self):
387+
identifier = "a" * (MAX_CHARACTERS_IN_IDENTIFIER + 1)
388+
rel = DatabricksRelation.create(identifier=identifier)
389+
assert rel.identifier == identifier
390+
391+
def test_none_identifier_is_allowed(self):
392+
rel = DatabricksRelation.create(identifier=None, type="table")
393+
assert rel.identifier is None
394+
395+
373396
class TestDatabricksRenderLimited:
374397
def test_render_limited_with_empty_no_alias(self):
375398
relation = DatabricksRelation.create(

0 commit comments

Comments
 (0)