Psycopg2.errors.UndefinedTable: отношение "mydjangoapp_mymodel" не существует
Я управляю приложением django, созданным третьими лицами.
Я настроил в settings.py подключение к новой базе данных
'default': { # changed
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'waterwatch',
'USER': 'waterwatch_main',
'PASSWORD': '****',
'HOST': 'localhost',
}
Теперь я хочу заполнить новую базу данных таблицей из моего models.py, то есть
class WaterConsumption(models.Model):
Id = models.IntegerField(primary_key=True)
Suburb = models.CharField(max_length=100)
NoOfSingleResProp = models.IntegerField()
AvgMonthlyKL = models.IntegerField()
AvgMonthlyKLPredicted = models.IntegerField()
PredictionAccuracy = models.IntegerField()
Month = models.CharField(max_length=50)
Year = models.IntegerField()
DateTime = models.DateTimeField()
geom = models.PointField()
def __str__(self):
return self.Suburb
class Meta:
verbose_name_plural = 'WaterConsumption'
поэтому я бегу
python manage.py makemigrations
но я получаю
django.db.utils.ProgrammingError: relation "waterwatchapp_waterconsumption" does not exist
Ну... Думаю, это очевидно, на самом деле я пытаюсь создать новые таблицы в моей новой базе данных.
Наверное, что-то не так с миграцией.
Итак, я удалил и заново создал базу данных, удалил все файлы в
waterwatchapp/migrations
, кроме__init__.py
waterwatchapp/__pycache__
waterwatch/__pycache__
Но когда я снова запускаю python manage.py makemigrations
или python manage.py migrate
, я все равно получаю ту же ошибку.
Почему django не создает таблицы заново?
Мне кажется, что django все еще каким-то образом отслеживает то, что было в базе данных раньше.
Как удалить всю историю миграций, сделанную ранее, и заставить django применить миграции к новой базе данных? (Я не забочусь о сохраненных данных)
Завершить отслеживание.
Заглянув глубже в Traceback, я заметил этот фрагмент
File "/home/tommaso/tommaso03/coding_projects/corsi_udemy/create-smart-maps-in-python-and-leaflet/waterwatch/venv/lib/python3.10/site-packages/django/contrib/admin/__init__.py", line 24, in autodiscover
autodiscover_modules('admin', register_to=site)
Это заставило меня подумать, что django пытался получить доступ к таблице до того, как она была создана, что вызвало ошибку.
Это было сделано waterwatchapp/admin.py
.
df_excelReader = pd.read_excel(BASE_DIR / 'tabledata_source/waterwatch_clean2.xlsx')
for index, row in df_excelReader.iterrows():
Id = index
Suburb = row['Suburb']
NoOfSingleResProp = row['Number of single-residential properties_number']
AvgMonthlyKL = row['Oct 2017\nkl/month']
AvgMonthlyKLPredicted = 0
PredictionAccuracy = 0
Month = row ['Month']
Year = row['Year']
DateTime = datetime.now()
Longitude = row['Longitude']
Latitude = row['Latitude']
WaterConsumption(Id=Id,
Suburb=Suburb,
NoOfSingleResProp=NoOfSingleResProp,
AvgMonthlyKL=AvgMonthlyKL,
AvgMonthlyKLPredicted=AvgMonthlyKLPredicted,
PredictionAccuracy=PredictionAccuracy,
Month=Month,
Year=Year,
DateTime=DateTime,
geom=Point(Longitude, Latitude)
).save()
Я закомментировал все строки кода waterwatchapp/admin.py
, включающие таблицу, на которую указывает трассировка (WaterConsumption
, в трассировке она выглядит как djangoapp_djangomodel, все строчные буквы), затем я выполнил
python manage.py makemigrations
и это сработало!
Затем я декомментировал строки.
Кроме того, я нашел довольно неэлегантный способ избежать этого комментирования и некомментирования.
Я добавил сниппет, который обращается к таблице только в том случае, если она уже существует. Кроме того, простая попытка исключения могла бы справиться с этой задачей.
for index, row in df_excelReader.iterrows():
Id = index
Suburb = row['Suburb']
NoOfSingleResProp = row['Number of single-residential properties_number']
AvgMonthlyKL = row['Oct 2017\nkl/month']
AvgMonthlyKLPredicted = 0
PredictionAccuracy = 0
Month = row ['Month']
Year = row['Year']
DateTime = datetime.now()
Longitude = row['Longitude']
Latitude = row['Latitude']
# introducing a condition, to avoid django access the model when it is not created yet
from django.db import connection
all_tables = connection.introspection.table_names()
table_name = 'waterwatchapp' + '_' + 'WaterConsumption'.lower()
if table_name in all_tables:
WaterConsumption(Id=Id,
Suburb=Suburb,
NoOfSingleResProp=NoOfSingleResProp,
AvgMonthlyKL=AvgMonthlyKL,
AvgMonthlyKLPredicted=AvgMonthlyKLPredicted,
PredictionAccuracy=PredictionAccuracy,
Month=Month,
Year=Year,
DateTime=DateTime,
geom=Point(Longitude, Latitude)
).save()