Opened 9 years ago

Closed 9 years ago

#24040 closed Uncategorized (invalid)

_meta.db_table malformed in SQL statement when >31char

Reported by: JorisBenschop Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by JorisBenschop)

I cant imagine this is not a known issue, but I havent been able to find it. Please show me the duplicate if there is one.

EDIT: https://docs.djangoproject.com/en/dev/ref/databases/#naming-issues.

I still think this is unnecessarily confusing. The hash is created to comply with the oracle 32-char backend, but as we all know, the hash has a 100% guarantee on failure. So why not catch this error in Django instead of sending bad data over the line, and creating a cryptic output that can only be understood if the DB output is set to debug. The current solution makes no sense. I mean, even truncating would be easier as it also yields a non-existing table, but it saves running the code that creates the hash.

original report:
If I create a model (django dev, oracle 11.2 backend), the sql statement is distorted if the db_table is over 31 characters. Almost like a buffer overflow:

GOOD:

_meta.db_table='variant_owr\".\"biomaterial_type'

DEBUG (0.003) QUERY = u'SELECT COUNT(:arg0) AS "__COUNT" FROM "VARIANT_OWR"."BIOMATERIAL_TYPE"' - PARAMS = (u'*',); args=('*',)

BAD:

_meta.db_table='variant_ownr\".\"biomaterial_type'

DEBUG (0.002) QUERY = u'SELECT COUNT(:arg0) AS "__COUNT" FROM "VARIANT_OWNR"."BIOMATERIAL92C0"' - PARAMS = (u'*',); args=('*',)

_meta.db_table = 'ababababababxxxabababababababab'

DEBUG (0.004) QUERY = u'SELECT COUNT(:arg0) AS "__COUNT" FROM "ABABABABABABXXXABABABABABACAD7"' - PARAMS = (u'*',); args=('*',)

Change History (6)

comment:1 by JorisBenschop, 9 years ago

Description: modified (diff)
Summary: _meta.db_name malformed when >30char_meta.db_table malformed in SQL statement when >31char

in reply to:  description comment:2 by JorisBenschop, 9 years ago

Description: modified (diff)
Severity: Release blockerNormal

no comment. user error

Last edited 9 years ago by JorisBenschop (previous) (diff)

comment:3 by JorisBenschop, 9 years ago

Description: modified (diff)

comment:4 by Tim Graham, 9 years ago

Are you complaining about having to quote the name on a legacy database? The rationale for hashing the name is to prevent tables with models with the same first 32 characters from conflicting. That is why simply truncating the name isn't a sufficient solution.

in reply to:  4 comment:5 by JorisBenschop, 9 years ago

Replying to timgraham:

Are you complaining about having to quote the name on a legacy database? The rationale for hashing the name is to prevent tables with models with the same first 32 characters from conflicting. That is why simply truncating the name isn't a sufficient solution.

My primary issue was that I failed to miss the documentation that described this limitation. Stackoverflow issues suggest I use db_table='schema\".\".actual_table', which gives an error.

What I am complaining about is that the hashing is not a good solution, because it always creates a cryptic error at the database level which is difficult to catch at application level. Instead of the hashing, an error should be raised at the application level explaining to the user that the name is too long. IMO this is not more code than the hashing, does not annoy the DB backend by trying to retrieve data from non-existent tables and thus results in better software.

Currently there is code that splits the schema and table name. Adding a single "assert len()" at that position will make life easier for oracle users.

again, thanks for your time and patience

comment:6 by Tim Graham, 9 years ago

Resolution: invalid
Status: newclosed

Unless I've missed something, hashing only creates a problem when you are integrating with a legacy database. If your tables are generated by Django, there should be no problems.

I don't think we are going to abandon our current solution due to backwards compatibility and the fact that it's advantageous for third-party apps with long identifiers where you can't set db_table manually.

If you have other ideas or if I've missed something, please reopen.

Note: See TracTickets for help on using tickets.
Back to Top