i have developed a database for a client that uses camel casing in the
database. we are now trying to get a models.py file to mimic the
database structure and i have run into a few bugs with regards to
using quoted table names.

The first issue is when you specify a foreign key field it takes the
table name + the field name to generate a unique constraint name. This
logic does not take into consideration that the field name has quotes
around it so it fails when executing the sql to create the foreign key
constraint. This wouldnt be so much of a problem if you could specify
the name of the foreign key (which I use through the related_name
parameter) and the engine would actually use it as the constraint
name.

The code is located in creation.py in sql_for_pending_references():

final_output.append(style.SQL_KEYWORD('ALTER TABLE') +
                    ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES
%s (%s)%s;' %
                    (qn(r_table), qn(truncate_name(
                        r_name,
self.connection.ops.max_name_length())),
                    qn(r_col), qn(table), qn(col),
                    self.connection.ops.deferrable_sql()))

I have personally changed the code above this to include:

#if the related_name property is set then use it as the foreign key
name, otherwise generate it as before

if f.rel.related_name == '':
                    r_name = '%s_refs_%s_%s' % (r_col, col,
self._digest(r_table, table))
                    r_name = r_name.replace('"','')
                else:
                                    r_name = f.rel.related_name

This gets rid of the errors creating the constraint.

The next problem is somewhat similar. The django toolkit tries to
automatically create indexes on foreign key fields but doesnt take
into consideration that the table has quotes around it OR that the
table is in a schema.
Note that I override the db_table to force it to be in a schema.

In the django code in creation.py:

def get_index_sql(index_name, opclass=''):
                return (style.SQL_KEYWORD('CREATE INDEX') + ' ' +
 
style.SQL_TABLE(qn(truncate_name(index_name,self.connection.ops.max_name_length()))).replace('"','').replace('.',
'_') + ' ' +
                        style.SQL_KEYWORD('ON') + ' ' +
                        style.SQL_TABLE(qn(db_table)) + ' ' +
                        "(%s%s)" % (style.SQL_FIELD(qn(f.column)),
opclass) +
                        "%s;" % tablespace_sql)

I have added the ".replace('"','').replace('.', '_')" part to format
the name properly to account for customized table names.

I am sure there are other areas that have this issue, but havent
encountered them yet. What do you think about including this into the
next version of django?

Here is my PY file:

class Application(models.Model):
   class Meta:
       db_table = '"dim"."Application"'
   ApplicationKey = models.AutoField(primary_key=True, db_column =
'"ApplicationKey"')
   ParentApplicationKey = models.ForeignKey('Application',
related_name = '"fkParentApplicationKey"', db_column =
'"ParentApplicationKey"', to_field = '"ApplicationKey"')
   Name = models.CharField(max_length=256, db_column = '"Name"')
   Description = models.TextField(db_column = '"Description"')
   CPE = models.CharField(max_length=256, db_column = '"CPE"')
   SurrogateKey = models.IntegerField(db_column = '"SurrogateKey"')
   SurrogateParentKey = models.IntegerField(db_column =
'"SurrogateParentKey"')
   DataSourceKey = models.ForeignKey('DataSource', related_name =
'"fkDataSourceKey"', db_column = '"DataSourceKey"')

class DataSource(models.Model):
   class Meta:
       db_table = '"dim"."DataSource"'
   DataSourceKey = models.AutoField(primary_key=True, db_column =
'"DataSourceKey"')
   DataSourceType = models.IntegerField(db_column =
'"DataSourceType"')
   Enabled = models.BooleanField(db_column = '"Enabled"')
   Name = models.CharField(max_length=256, db_column = '"Name"')
   Description = models.CharField(max_length=4000, db_column =
'"Description"')
   HostName = models.CharField(max_length=256, db_column =
'"HostName"')
   UserName = models.CharField(max_length=256, db_column =
'"UserName"')
   Password = models.CharField(max_length=256, db_column =
'"Password"')
   APIVersion = models.CharField(max_length=256, db_column =
'"APIVersion"')

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to