Opened 10 years ago
Closed 10 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 )
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 , 10 years ago
Description: | modified (diff) |
---|---|
Summary: | _meta.db_name malformed when >30char → _meta.db_table malformed in SQL statement when >31char |
comment:2 by , 10 years ago
Description: | modified (diff) |
---|---|
Severity: | Release blocker → Normal |
comment:3 by , 10 years ago
Description: | modified (diff) |
---|
follow-up: 5 comment:4 by , 10 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.
comment:5 by , 10 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 , 10 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
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.
Replying to JorisBenschop:
EDIT: https://docs.djangoproject.com/en/dev/ref/databases/#naming-issues