Запрос Django завершается ошибкой с _id, который не используется, не создается и не ссылается на

#django #foreign-keys #django-queryset

Вопрос:

Я уже использовал набор запросов раньше, хотя это моя первая попытка объединить таблицы, но пока она не работает. Я использую django 3.2 и python 3.8.1

мой models.py

 class Mainjoinbook(models.Model):
    fullsitename = models.TextField(primary_key=True)
    creationdate = models.DateTimeField()
    entrytypeid = models.BigIntegerField(blank=True, null=True)
    title = models.TextField(blank=True, null=True)
    tickettype = models.TextField(blank=True, null=True)
    ticket = models.TextField(blank=True, null=True)
    status = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'mainlogbook'

class Sitelocation(models.Model):
    site_name = models.TextField(primary_key=True)
    latitude = models.TextField(blank=True, null=True)
    longitude = models.TextField(blank=True, null=True)
    sites = models.ForeignKey(Mainjoinbook, on_delete=models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'tblsiteaccess'
 

Я пытаюсь объединить все значения из обеих таблиц в моей views.py

 qrylocations = Sitelocation.objects.select_related('sites').filter(sites__status='OPEN')
 

это приводит к этой ошибке, так как этот столбец создан django, но не принадлежит таблице. Я все еще не могу понять, как решить эту проблему, так как я перепробовал много вариантов, но всегда попадаю в какую-то ошибку, и я надеюсь, что кто-то может помочь мне понять, что я делаю неправильно при объединении таблиц с определенными первичными ключами

 psycopg2.errors.UndefinedColumn: column tblsiteaccess.sites_id does not exist
 

вывод SQL показан следующим образом.

вывод из qrylocations.запрос

 SELECT "tblsiteaccess"."site_name", "tblsiteaccess"."latitude", "tblsiteaccess"."longitude", "tblsiteaccess"."sites_id", "mainlogbook"."fullsitename", "mainlogbook"."log_id", "mainlogbook"."creationdate", "mainlogbook"."entrytypeid", "mainlogbook"."title", "mainlogbook"."tickettype", "mainlogbook"."ticket", "mainlogbook"."status" FROM "tblsiteaccess" INNER JOIN "mainlogbook" ON ("tblsiteaccess"."sites_id" = "mainlogbook"."fullsitename") WHERE "mainlogbook"."status" = OPEN
 

Комментарии:

1. Вы сделали эту таблицу с помощью inspectdb ? Знаете ли вы фактическое имя столбца внешнего ключа sites в таблице tblsiteaccess ?

2. Если вы создадите a ForeignKey , то Django обычно добавит _id имя для соответствующего столбца в базе данных.

3. да @AbdulAzizBarkat, таблицы в моделях взяты из inspectdb . sites столбец был только для внешнего ключа, его нет в таблице. Я ожидаю получить JOIN ON "tblsiteaccess"."site_name" = "mainlogbook"."fullsitename" , что, очевидно, я делаю это неправильно

4. @engstuff это не очень хороший первичный ключ, что происходит, когда кто-то хочет изменить имя Mainjoinbook объекта? Это неэффективно…

Ответ №1:

A ForeignKey , естественно, нуждается в столбце в таблице базы данных. Поскольку site_name сам по себе является первичным ключом, вы должны использовать его как ForeignKey здесь, вместо этого вместо ForeignKey этого должен быть OneToOneField [Django docs], поскольку он также является первичным ключом и должен быть уникальным:

 class Sitelocation(models.Model):
    site_name = models.OneToOneField(
        Mainjoinbook,
        on_delete=models.CASCADE,
        primary_key=True,
        db_column='site_name'
    )
    latitude = models.TextField(blank=True, null=True)
    longitude = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'tblsiteaccess'
 

Комментарии:

1. спасибо @Абдул Азиз Баркат , как я уже сказал, я знал, что делаю что-то не так, и чтение всех документов сбивало меня с толку еще больше. это помогло мне намного лучше понять, как работает иностранный ключ