django: ContentType matching query does not exist.

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich hab vor einiger Zeit mit den "fixtures" gespielt und das zum dumpen der DB Daten zu benutzten. Dabei hat das aber nicht funktioniert.
Beim einspielen des Dumps kommt u.a. der Fehler:
ContentType matching query does not exist.
siehe auch: http://groups.google.com/group/django-u ... bc4773dec7

Nun wollte ich was anderes machen: Eine neuer User-Gruppe anlegen. Dabei kommt genau der selbe Fehler.
Jetzt hab ich allerdings mal den Traceback näher angesehen. Anscheinend liegt das am auth system.

Django legt offensichtlich für jedes Model direkt ein paar Sachen im auth system automatisch an:
Der "Content Type" wird in der Tabelle "django_content_type" angelegt. Dabei ist es nichts anderes als der Name einer Modell-Klasse, versehen mit einer ID.
In der Tabelle "auth_permission" wird zu jedem dieser "Content Type" drei einträge hinterlegt: "add_blablabla", "change_blablabla" und "delete_blablabla"

Darüber kann man also regeln welcher User was darf...

Nun zu meinem Fehler:

Ich hab bei PyLucid so nach und nach einige Model-Klassen rausgeworfen, weil sie überflüssig sind.
Nun sind aber in den oben genannten django Tabellen noch die Einträge vorhanden... Kann es sein, das es deswegen zu dem Fehler kommt???

Bietet django nicht irgenwo die Möglichkeit, automatisch "verwaiste" Einträge in den Internen Tabellen zu löschen??? Oder muß man das selber machen?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab angefangen im PyLucid _install Bereich eine Funktion zu schaffen, damit man diese Überbleibsel automatisch entfernen kann...

Ich habs aber gerade erst angefangen: http://pylucid.net/trac/changeset/943

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich hab das Problem auch mal in der Maillingliste geschrieben:
http://groups.google.com/group/django-u ... ff91614ab8

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So... Mit http://pylucid.net/trac/changeset/944 ist es nun scharf gestellt... Nun werden erstmal alle content_types gelöscht, die nicht mehr in der App. vorkommen.
Danach werden alle permission Einträge gelöscht, zu den es keine content_types mehr gibt...

Nun kann ich eine User-Group anlegen, ohne das der Fehler "ContentType matching query does not exist." auftaucht.

Allerdings sehe ich damit nun, das es neue Probleme gibt :(
So einige permissions-Einträge verweisen zwar auf existierende content_types, zumindest existieren dazu IDs in der DB. Dennoch sind sie falsch, bzw. sind für andere, gelöschte Model-Klassen.

Die einfachste Methode das ganze sauber zu reparieren, wäre es wohl, die Tabelle "django_content_type" und "auth_permission" zu löschen. Nach einem syncdb werden sie ja wieder neu angelegt.
Dumm wäre es allerdings, wenn das ganze in einem Produktiv-System auftauchen würde. In dem Falle existieren evtl. aufwendig erstellte User-Gruppen und die sind logischerweise nach dem löschen und wiederanlegen alle resettet...

Übersehe ich das was??? Oder gibt es einfach noch niemanden, der mal ein Modell-Klasse nachträglich gelöscht hat? Gibt es vielleicht dazu eine Funktion in django um verwaiste Einträge automatisch zu löschen?

Jedenfalls hat in den newsgroups noch niemand eine Anmerkung gemacht...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Übersehe ich das was??? Oder gibt es einfach noch niemanden, der mal ein Modell-Klasse nachträglich gelöscht hat? Gibt es vielleicht dazu eine Funktion in django um verwaiste Einträge automatisch zu löschen?
Ich habe nun nicht so viel mit Django zu tun... aber... wozu brauchst du das? Verwaiste Einträge aus der DB rausfischen. Wie sollen solche entstehen?

Und... Modellklasse löschen?

Für mich klingt das sehr nach einer Lösung eines Problems, welches es nicht wirklich gibt.


MfG EnTeQuAk
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

EnTeQuAk hat geschrieben:Verwaiste Einträge aus der DB rausfischen. Wie sollen solche entstehen?

Und... Modellklasse löschen?
Ganz einfach. Du Machst ein Model, was im Endeffekt eine neue Tabelle ist. Mit "syncdb" wird diese Erstellt. Aber nicht nur das. django erstellt für das Model auch gleich ein contenttype Eintrag (django.contrib add-on) und macht Einträge für Die permissions... Im Grunde eine gute Sache ;)

Wenn du später eine dieser Modell-Klassen löscht, weil die DB-Tabelle nicht mehr benötigt wird, dann bleiben erstmal alle diese Einträge bestehen.
Auf den ersten Blick sind ein paar überflüssige DB Einträge nicht schlimm... Allerdings funktioniert teilweise ein paar Dinge nicht mehr. z.B. das mit dem Traceback beim User-Gruppe-anlegen. Siehe vorherige Posts von mir.

Im Grunde ist es das allgemeine Problem, was man hat, wenn man ein bestehendes Datenbank-Modell im nachhinein ändert, siehe http://www.python-forum.de/topic-10373.html

Offensichtlich sind alle django Benutzter wahre Profis. Da stimmt das DB-Modell von vornherein immer und man muss nie was ändern :?

EDIT: Noch ein anderer Fall: Das ganze entsteht aus, wenn du mal eine andere django-App testen willst. Dabei werden ja auch alle Modelle in der DB erzeugt. Wenn du die App aber dann noch nicht benutzten willst, hast du auch Leichen im Keller...

EDIT2: So könnte ein standalone Skript aussehen, um die Tabellen zu säubern: http://paste.pocoo.org/show/1482/

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:Offensichtlich sind alle django Benutzter wahre Profis. Da stimmt das DB-Modell von vornherein immer und man muss nie was ändern :?
Nö. Bei mir ändert sich das Layout in einigen Projekten ganz häufig, weil irgendwelche Leute meinen sich nie festlegen zu wollen. Aber Fehler treten bei mir meist nur auf, wenn irgendwelche Relationen in der Datenbank nicht mit denen in den Modelldefinitionen übereinstimmen. Aber dann reicht auch ein Kurzer Abstecher in ``psql``, um das Problem zu beheben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Hatte das Problem ebenfalls noch nie. Wenn ich Änderungen an der Struktur mache drope ich die Tables und mache sie neu. Wenn dann die Änderungen auf den Produktivserver kommen gibts eine update.sql.

s/mache/machte/
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

blackbird hat geschrieben:Wenn dann die Änderungen auf den Produktivserver kommen gibts eine update.sql.
Das funktioniert allerdings nur dann, wenn die von SQL vergebenen IDs genau übereinstimmen ;) Ich würde mal sagen, das dürfte unwahrscheinlich sein. Es sei denn du hast auf beiden Systemen exakt das selbe in der gleichen Reihenfolge gemacht...

Wenn du z.B. eine Benutzergruppe eingerichtet hast und verschiedene Rechte vergeben hast, dann sind so einige IDs mit anderen IDs verknüpft.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben:Das funktioniert allerdings nur dann, wenn die von SQL vergebenen IDs genau übereinstimmen
Hallo Jens!

Ich glaube, man kann bei MySQL mit ``INSERT_ID = <zahl>`` den Wert des AUTO_INCREMENT-Feldes vorbelegen. Oder ist es nicht so, dass man bei MySQL AUTO_INCREMENT-Felder einfach überschreiben kann? Ich weiß es nicht mehr.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich denke schon, das man das AUTO_INCREMENT Feld vorbelegen kann. Das löst aber IMHO nicht das Problem.

Es gibt bei django Tabellen, wie "auth_group_permissions" oder "auth_user_user_permissions" wo IDs mit IDs verknüpft sind.

Die Tabellen sehen so aus:

Code: Alles auswählen

CREATE TABLE `auth_group_permissions` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `group_id` integer NOT NULL REFERENCES `auth_group` (`id`),
    `permission_id` integer NOT NULL REFERENCES `auth_permission` (`id`),
    UNIQUE (`group_id`, `permission_id`)
);
CREATE TABLE `auth_user_user_permissions` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `user_id` integer NOT NULL REFERENCES `auth_user` (`id`),
    `permission_id` integer NOT NULL REFERENCES `auth_permission` (`id`),
    UNIQUE (`user_id`, `permission_id`)
);
Wie man sieht, ist die UserGruppe bzw. der User mit den "auth_permission" verknüpft.
Wie ich oben ausgeführt hab, kann es bei Umstrukturierungen vorkommen, das "auth_permission" Einträge wegfallen. In dem Falle hat man also ein paar "ungültige/nicht belegte" Verknüpfungen in der DB.

Ich weiß in dem Falle nicht konkret, was passieren kann. Vielleicht ist es bei der Rechtevergabe auch egal, wenn alte Verknüpfungen übrig bleiben. Beim wegfall von "ContentType" Einträgen ist es jedenfalls ein Problem, siehe oben.

Die Frage ist, ob django nicht bei einem "syncdb" alte Einträge löschen sollte, so wie es mein vorgestelltes Skript macht.

EDIT: Ich hab nochmal versucht das Problem in der django-dev ML zu schildern: http://groups.google.com/group/django-d ... cd80?hl=de

EDIT2: Ich hab gerade was interessantes gefunden: http://groups.google.com/group/django-u ... cc063a93cc
Da gehts um das "ContentType" Problem.
In django.contrib.contenttypes.management gibt es create_contenttypes() und create_all_contenttypes()...
Allerdings denke ich, das man damit nur fehlende contenttypes erzeugen kann, was ja "syncdb" macht. Es wird aber nix aufgeräumt...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten