Opened 14 years ago

Closed 14 years ago

Last modified 14 years ago

#14179 closed (invalid)

django create table with capitalized chars

Reported by: Boris Savelev Owned by: nobody
Component: Uncategorized Version: 1.2
Severity: 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

Hello!

I have a model like this:

...

class OrganizationType(models.Model):
  name         = models.CharField(max_length = 255, unique = True)

  def __unicode__(self):
    return self.name

  class Meta:
    ordering = ('name',)

class Parameter(models.Model):
  code               = models.PositiveIntegerField()
  name               = models.CharField(max_length = 255)
  description        = models.TextField(null = True, blank = True)
  weight             = models.PositiveIntegerField()
  group              = models.ForeignKey(Subcategory)
  type               = models.ForeignKey(ParameterType)
  organizationType   = models.ManyToManyField(OrganizationType)
  exclude            = models.ManyToManyField(Organization, null = True, blank = True)

  def __unicode__(self):
    return '%d.%d.%d. %s' % (self.group.group.code, self.group.code, self.code, self.name)

  def fullcode(self):
    return '%d.%d.%d' % (self.group.group.code, self.group.code, self.code)

  class Meta:
    unique_together = (
      ('name', 'group'),
      ('code', 'group'),
    )
    ordering = ('group__group__code', 'group__code', 'code')

...

python manage.py sql appname generate SQL:

...

BEGIN;
CREATE TABLE "exmo2010_organizationtype" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(255) NOT NULL UNIQUE
)
;
CREATE TABLE "exmo2010_parameter_organizationType" (
    "id" integer NOT NULL PRIMARY KEY,
    "parameter_id" integer NOT NULL,
    "organizationtype_id" integer NOT NULL REFERENCES "exmo2010_organizationtype" ("id"),
    UNIQUE ("parameter_id", "organizationtype_id")
)
;
CREATE TABLE "exmo2010_parameter" (
    "id" integer NOT NULL PRIMARY KEY,
    "code" integer unsigned NOT NULL,
    "name" varchar(255) NOT NULL,
    "description" text,
    "weight" integer unsigned NOT NULL,
    "group_id" integer NOT NULL REFERENCES "exmo2010_subcategory" ("id"),
    "type_id" integer NOT NULL REFERENCES "exmo2010_parametertype" ("id"),
    UNIQUE ("name", "group_id"),
    UNIQUE ("code", "group_id")
)
;

...

in this line CREATE TABLE "exmo2010_parameter_organizationType" table name contains capital letter 'T'. I think this is an error, isn't it?

Change History (6)

comment:1 by Boris Savelev, 14 years ago

error was in line

organizationType   = models.ManyToManyField(OrganizationType)

this field is the source of table name for ManyToMany relation. When I lower this field name django generate right sql. So, I don't know, bug this or not.

comment:2 by Russell Keith-Magee, 14 years ago

Resolution: invalid
Status: newclosed

Yes, it's an inconsistency with table naming, but it's required to maintain backwards compatibility (and we can't change it without breaking backwards compatibility). The name is quoted, so it shouldn't make any difference to the SQL that runs.

comment:3 by Boris Savelev, 14 years ago

ok, but I think that this fact must be described in documentation

comment:4 by Russell Keith-Magee, 14 years ago

Why? As an end user, you shouldn't ever have to care about table names.

comment:5 by Boris Savelev, 14 years ago

in reply to:  5 comment:6 by Ramiro Morales, 14 years ago

Replying to boris:

I expect that all table names are lowercase as described in tutorial
http://docs.djangoproject.com/en/dev/intro/tutorial01/#activating-models

The name of the automatic intermediate table generated for a m2m field is built from: a) the name of the app, b) the name of the table of the model defining the m2m relationship and c) the name of the actual m2m field itself, e.g.:

from django.db import models

class ModelA(models.Model):
    name = models.CharField(max_length=20)

class ModelB(models.Model):
    name = models.CharField(max_length=20)
    foo = models.ManyToManyField(ModelA, related_name='modelsb1')
    BaR = models.ManyToManyField(ModelA, related_name='modelsb2')
BEGIN;CREATE TABLE "t14179_modela" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(20) NOT NULL
)
;
CREATE TABLE "t14179_modelb_foo" (
    "id" integer NOT NULL PRIMARY KEY,
    "modelb_id" integer NOT NULL,
    "modela_id" integer NOT NULL REFERENCES "t14179_modela" ("id"),
    UNIQUE ("modelb_id", "modela_id")
)
;
CREATE TABLE "t14179_modelb_BaR" (
    "id" integer NOT NULL PRIMARY KEY,
    "modelb_id" integer NOT NULL,
    "modela_id" integer NOT NULL REFERENCES "t14179_modela" ("id"),
    UNIQUE ("modelb_id", "modela_id")
)
;
CREATE TABLE "t14179_modelb" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(20) NOT NULL
)
;COMMIT;

So, there is no relation between this and the section of the tutorial you quoted (it touches the topic of table names case only when it talks about the tables created for the models):

Table names are automatically generated by combining the name of the app (polls) and the lowercase name of the model -- poll and choice. (You can override this behavior.)

If you need to have consistent all-lowercase names for the automatically created intermediate table, then make sure you a) have a all-lowercase name for the model table (either by using the auto generated one or by using Meta.db_table) and b) define the m2m field with a all-lowercase name.

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