Code

Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#14179 closed (invalid)

django create table with capitalized chars

Reported by: boris 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: UI/UX:

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?

Attachments (0)

Change History (6)

comment:1 Changed 4 years ago by boris

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

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 Changed 4 years ago by russellm

  • Resolution set to invalid
  • Status changed from new to closed

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 Changed 4 years ago by boris

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

comment:4 Changed 4 years ago by russellm

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

comment:5 follow-up: Changed 4 years ago by boris

comment:6 in reply to: ↑ 5 Changed 4 years ago by ramiro

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.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.