2011-08-04 40 views
4

我使用Django与现有的Oracle数据库(即,其中表不是由Django创建的)。所以在我的模型中,我不得不通过在Meta类中为db_table指定一个值来指定表名。由于我希望访问的表属于不同于我拥有凭据的用户,因此我遇到了问题。我有权查看这些表格(在SQL Developer中没有麻烦)。能否阻止Django截断长表名?

当Oracle表的名称超过30个字节时,Django会截断名称的最后四个字节,并将其替换为表名剩余部分的可重复4字节散列。这对Django自己创建的表格非常有用。对于访问现有数据库中的表而言,这通常也不会成为问题(正如我的情况),因为Oracle本身将名称限制为30个字节。

的问题是,Django不具有用于指出的是,表属于另一个用户单独的设施。所以我用点语法的解决方法(由只设置db_table为,例如,“USERNAME.MY_29_BYTE_TABLE_NAMEXXXXXXXX”),但由于这导致整体表名超过30个字节,Django的做它截断伎俩,并试图对查询一个不存在的表名。

是否有办法防止这种行为,或以不同的方式来指定用户从表的名称分开?

+1

这听起来像它可能是在Django合法的错误!你应该看看是否有在https://code.djangoproject.com/query相关的任何东西,添加一个新的机票如果不。 – SingleNegationElimination

+1

考虑一个登录触发器,做和ALTER SESSION SET CURRENT_SCHEMA,而不是指定所有者为每个表 –

+0

很好的建议,无论是。如果我的理解正确,Gary的想法只有在你想访问的所有表都属于同一个用户时才有效。虽然对我来说就是这样,但对于其他情况,下面SuperDuper建议的解决方案可能更有用。谢谢! –

回答

2

截断是在Oracle Django DB后端由quote_name方法引起的,该方法遵循SQL92要求并使用硬编码值max_name_length

您可以通过创建自定义数据库后端或猴补丁像这样覆盖此行为:

from django.db.backends.oracle.base import DatabaseOperations 
DatabaseOperations.max_name_length = lambda s: <NEW_MAX_VALUE> 

这真不明白为什么你需要在表名超过30个字符,因为它违反了Oracle Schema Object Naming Rules

+0

这告诉我如何防止这种行为。谢谢!实际上,我没有指定大于30个字符的表名,Django认为我是因为需要额外的字节来指示用户。我想这个解决方案将不会在情况如此可行的,你有Django的生成的表格(即使用默认的APPNAME_MODLENAME命名约定)和甲骨文预先存在的表的结构,因为如果你提出这个值的Django真的可以尝试创建名称过长的表。但我想你可以通过在这种情况下总是指定db_table来控制它。 –