Skip to content

Commit c7f353f

Browse files
fix: make max table name length backend-specific (64 MySQL, 63 PostgreSQL)
MySQL allows 64-character identifiers; PostgreSQL allows 63 (NAMEDATALEN-1) and silently truncates longer names. Add max_table_name_length property to the adapter ABC (default 64), override to 63 in PostgreSQLAdapter. Replace the hardcoded MAX_TABLE_NAME_LENGTH constant in declare.py. No backward compatibility impact — MySQL keeps 64, PostgreSQL gets the correct 63. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8de3714 commit c7f353f

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

src/datajoint/adapters/base.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,18 @@ def make_full_table_name(self, database: str, table_name: str) -> str:
259259
"""
260260
return f"{self.quote_identifier(database)}.{self.quote_identifier(table_name)}"
261261

262+
@property
263+
def max_table_name_length(self) -> int:
264+
"""
265+
Maximum length of a table name for this backend.
266+
267+
Returns
268+
-------
269+
int
270+
Maximum allowed characters in a table identifier.
271+
"""
272+
return 64 # safe default (MySQL limit)
273+
262274
# =========================================================================
263275
# Type Mapping
264276
# =========================================================================

src/datajoint/adapters/postgres.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,11 @@ def quote_identifier(self, name: str) -> str:
249249
"""
250250
return f'"{name}"'
251251

252+
@property
253+
def max_table_name_length(self) -> int:
254+
"""PostgreSQL NAMEDATALEN-1 = 63."""
255+
return 63
256+
252257
def split_full_table_name(self, full_table_name: str) -> tuple[str, str]:
253258
"""Split ``"schema"."table"`` into ``('schema', 'table')``."""
254259
schema, table = full_table_name.replace('"', "").split(".")

src/datajoint/declare.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
# Get SQL mapping for core types
5353
CORE_TYPE_SQL = {name: sql_type for name, (_, sql_type) in CORE_TYPES.items()}
5454

55-
MAX_TABLE_NAME_LENGTH = 63 # PostgreSQL NAMEDATALEN-1; MySQL allows 64 but 63 is safe for both
5655
CONSTANT_LITERALS = {
5756
"CURRENT_TIMESTAMP",
5857
"NULL",
@@ -435,10 +434,10 @@ def declare(
435434
# Parse table name using adapter (handles backend-specific quoting)
436435
schema_name, table_name = adapter.split_full_table_name(full_table_name)
437436

438-
if len(table_name) > MAX_TABLE_NAME_LENGTH:
437+
if len(table_name) > adapter.max_table_name_length:
439438
raise DataJointError(
440439
"Table name `{name}` exceeds the max length of {max_length}".format(
441-
name=table_name, max_length=MAX_TABLE_NAME_LENGTH
440+
name=table_name, max_length=adapter.max_table_name_length
442441
)
443442
)
444443

0 commit comments

Comments
 (0)