Tuesday, July 30, 2019

Problem with migrating a fresh db - jango.db.utils.ProgrammingError: column "structure_depth" specified more than once

Hey everybody,

I hope I can somehow give enough informations but also keep it as little as possible.

situation is:
- existing migrations deleted to reset migrations (existing migrations seem are broken aswell, for a fresh db)
- new migrations with makemigrations
- migrate fails with:

 File "/Users/user/.pyenv/versions/systori-python/lib/python3.6/site-packages/django/db/backends/utils.py", line 83, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: column "structure_depth" specified more than once

Maybe related, this doesn't happen when I run the tests.

And indeed, if I print the sql statement in above mentioned line, I see:

CREATE TABLE "project_project" 

  ("id" serial NOT NULL PRIMARY KEY,

   "name" varchar(512) NOT NULL,

   "description" text NULL,

   "is_template" boolean NOT NULL,

   "structure" varchar(64) NOT NULL,

   "phase" varchar(50) NOT NULL,

   "state" varchar(50) NOT NULL,

   "structure_depth" integer NOT NULL CHECK ("structure_depth" >= 0),

   "structure_depth" integer NOT NULL CHECK ("structure_depth" >= 0)

)


if I print the same when running tests the "structure_depth" isn't present twice.


while surfing around with PyCharms nice Debugger I figured that at some point there is an object model, which represents the right model, but model._meta.fields already has the duplicate of "structure_depth". other parts I can find, f.e. something like a ProjectState doesn't have the duplicate "structure_depth". This is all way beyond my current understanding of Django.


the generated migrations.CreateModel looks correct, "structure_depth" appears only once.


the model is, shortened:


class Project(models.Model):

    structure = GAEBStructureField(

        _("Numbering Structure"), default="01.01.001"

    )  # GAEBStructureField adds structure_depth


the custom Field is defined as follows:


class GAEBStructureField(models.Field):

    description = _("Pattern for the GAEB hierarchy code structure.")


    def __init__(self, *args, **kwargs):

        kwargs["max_length"] = 64

        super().__init__(*args, **kwargs)


    def deconstruct(self):

        name, path, args, kwargs = super().deconstruct()

        del kwargs["max_length"]

        return name, path, args, kwargs


    def contribute_to_class(self, cls, name, **kwargs):

        super().contribute_to_class(cls, name)


        setattr(cls, name, GAEBStructureProperty(name))


        depth_name = name + "_depth"

        depth_field = models.PositiveIntegerField(editable=False, db_index=True)

        cls.add_to_class(depth_name, depth_field)

        setattr(

            cls,

            depth_name,

            property(

                fget=lambda obj: obj.__dict__[depth_name], fset=lambda obj, val: None

            ),

        )


so, I'm kind of proud what I've figured but I'm lost in non-linear land - at least it feels like it. I can't find the point where model._meta.fields actually gets created.


so, hopefully maybe someone can point me in the right direction, give some hints or just comment it - all appreciated.


this project is open source, so I could aswell just make a branch and upload current state. FYI github.com/systori/systori


thx in advance,

Marius

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/94d6f267-986c-48ee-b141-e91c25ec57da%40googlegroups.com.

No comments:

Post a Comment