2011-01-14 17 views
8

Ich habe ein Problem mit Django 1.2.4. HierDjango: DatabaseError Spalte existiert nicht

ist ein Modell:

class Foo(models.Model): 
    # ... 
    ftw = models.CharField(blank=True) 
    bar = models.ForeignKey(Bar, blank=True) 

Gleich nach der Datenbank Spülung benutze ich die Schale:

Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
[GCC 4.4.5] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
(InteractiveConsole) 
>>> from apps.foo.models import Foo 
>>> Foo.objects.all() 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 67, in __repr__ 
    data = list(self[:REPR_OUTPUT_SIZE + 1]) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 82, in __len__ 
    self._result_cache.extend(list(self._iter)) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 271, in iterator 
    for row in compiler.results_iter(): 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 677, in results_iter 
    for rows in self.execute_sql(MULTI): 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 732, in execute_sql 
    cursor.execute(sql, params) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/backends/util.py", line 15, in execute 
    return self.cursor.execute(sql, params) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute 
    return self.cursor.execute(query, args) 
DatabaseError: column foo_foo.bar_id does not exist 
LINE 1: ...t_omg", "foo_foo"."ftw", "foo_foo... 

Was mache ich falsch hier?

Aktualisieren: Wenn ich die ForeignKey auskommentieren, verschwindet das Problem.

Update 2: Merkwürdigerweise funktioniert dieses Gerät Test ganz gut:

def test_foo(self): 
    f = Foo() 
    f.save() 

    self.assertTrue(f in Foo.objects.all()) 

Warum es hier aber nicht in der Shell funktioniert?

Update 3: Der Grund, warum es in Unit-Tests funktioniert, jedoch nicht die Schale etwas mit den verschiedenen Datenbanken zu tun haben, verwendet werden:

settings.py:

DATABASES = { 
    'default': { 
     'ENGINE': 'postgresql_psycopg2', 
     'NAME': 'foo', 
     'USER': 'bar', 
     'PASSWORD': 'baz', 
     'HOST': '', 
     'PORT': '', 
    } 
} 

import sys 
if 'test' in sys.argv or True: 
    DATABASES = { 
     'default': { 
      'ENGINE': 'django.db.backends.sqlite3', 
      'NAME': 'testdb' 
     } 
    } 

Update 4: Bestätigt, dass alles funktioniert, wenn ich SQLite3 als db benutze.

+1

Um klar zu sein, haben Sie 'syncdb' in einer leeren Datenbank ausgeführt oder das Schema von Hand bearbeitet? Es scheint, als ob Sie wissen, dass ein modifiziertes Modell die Tabelle nicht automatisch aktualisiert ... aber nur dafür sorgen, – Robert

+0

Yeah, ich lief 'Syncdb'. –

+0

Ich möchte nur 100% sicher sein, dass es kein bestehendes Datenbankproblem ist: Haben Sie Ihre Postgres-Datenbank gelöscht und neu erstellt? Ich habe auf jeden Fall anhaltende Probleme gesehen, wenn Leute 'flush' oder teilweise syncdbs versuchen. Der Grund, den ich frage, ist, weil dies einen Gestank auslösen würde, wenn ein einfaches 2-Feld-Modell Spalten auf postgresql_psycopg2 nicht korrekt erstellt hätte. Haben Sie auch überprüft, ob 'foo_foo.bar_id' in' dbshell' existiert? Je mehr Infos, desto besser! –

Antwort

9

Versuchen Sie, die Datenbank vollständig zu löschen/zu löschen, bevor Sie syncdb ausführen.

Ich erinnere mich daran, dass ich das eine Weile zurück tun musste, als ich Änderungen an fremden Schlüsselfeldern vorgenommen hatte.

+5

In der Dokumentation zu django wird angegeben, dass syncdb keine vorhandenen Tabellen ändert. Wenn Sie also die Tabellen mit syncdb erstellt und dann einige Felder geändert haben, indem Sie das Modell geändert haben, müssen Sie alles löschen: './manage.py reset myapp' würde den Trick machen. Es funktioniert offensichtlich für Unittest, da Tabellen bei jedem Lauf neu erstellt werden. –

+1

Wenn Sie Ihre Datenbank nach jedem Modellwechsel nicht zurücksetzen möchten, versuchen Sie [South] (http://south.aeracode.org/). – Bjorn

0

Ich sah das gleiche Problem und bemerkte, dass in der Backend-Datenbank das Feld, das fremde Schlüssel beherbergt, nicht existierte. Das Problem ist verschwunden, nachdem ich das Feld erstellt habe (was ich für merkwürdig halte). Django scheint kein Feld zu erstellen, das als Fremdschlüssel gekennzeichnet ist. Irgendein Grund warum?

3

Ich habe dieses Problem behoben, indem ich die spezifische Tabelle auf dieses Frage-Modell löste. Dann verwendet:

python manage.py syncdb 

Wenn Sie PostgreSQL verwenden, dann empfehle ich mit phppgadmin sich eine Web-Oberfläche ähnlich wie phpMyAdmin, die für mySQL verwendet wird.

Alternative zu der Benutzeroberfläche können Sie einfach Kommandozeile

su postgres #change user to postgres 
psql <datebase> #access shell for <datebase> database 
\d #list all tables 
DROP TABLE "" CASCADE #select a table to drop 
\q #exit shell 

Wenn in \ d tun, entweichen durch q drücken.

3

Wenn Sie Django 1.8 verwenden, sollten Sie die Spalte erstellen. Um sicherzustellen, dass Sie die Spalte erstellen korrekt die Migrationsdatei finden, in dem Sie das Feld erstellt und ausgeführt:

./manage.py sqlmigrate app_name migration_name_sans_extension 

Dies wird Ausgabebefehle der SQL, um die Spalte zu erstellen. Stellen Sie sicher, dass Sie die Befehle einschließen, die Beziehungen behandeln, und führen Sie die Befehle in Ihrer Datenbankkonsole aus. Sie müssen etwas Extremes tun, wie den Tisch oder die Datenbank fallen zu lassen.

+0

Können Sie sagen, wie die Spalte aussehen soll? Zum Beispiel habe ich zwei ForeignKey-Spalten: referred_by und supported_by, die sich beide auf Benutzer beziehen. Ich würde dann zwei weitere Spalten hinzufügen: user_referred_by und user_supported_by und sie würden REFERENCE User (id) ?? Kannst du sagen, wo in den 1.8 docs dies abgedeckt ist? – highpost

+1

Zum Beispiel bekomme ich immer noch django.db.utils.ProgrammingError: Spalte user.referred_by_id ist nicht vorhanden. – highpost

+0

Die Spalten verweisen auf die ID, es sei denn, Sie geben ein to_field-Feld an. Ich bin nicht sicher, ob dies in den Dokumenten behandelt wird, aber die Informationen zu FK-Feldern finden Sie hier: https://docs.djangoproject.com/en/1.8/ref/models/fields/#foreignkey –

3

Bitte lesen Sie diese, bevor Sie Ihre gesamte DB fallen

ich gleiche Problem hatte. Bitte lesen Sie die Ausnahme vollständig durch. Ich hatte eine ModelForm-Klasse, die aus meiner Tabelle las, um ein Formular zu erstellen, und eine Ausnahme war dort. Ich habe die Makemigrationen auskommentiert und dann komplett ausgeführt. Danach habe ich die ModelForm-Klasse kommentiert und alles funktioniert perfekt.

Hoffe, das hilft.

Verwandte Themen