Пользовательский первичный ключ Django

Когда я проверяю базу данных Trac, я получаю:

class TicketChange(models.Model):
    ticket = models.IntegerField()
    time = models.BigIntegerField()
    author = models.TextField(blank=True)
    field = models.TextField()
    oldvalue = models.TextField(blank=True)
    newvalue = models.TextField(blank=True)
    class Meta:
        managed = False
        db_table = 'ticket_change'

С не первичным ключом:

>>> TicketChange.objects.all()
DatabaseError: column ticket_change.id does not exist
LINE 1: SELECT "ticket_change"."id", "ticket_change"."ticket", "tick...

Потому что мне нужно указать ПК, но оригинальный первичный ключ ticket_change в траке есть:

Primary key (ticket, time, field)

Но это не возможно в Django: Обсуждение первичного ключа из нескольких столбцов Django.

Если я определю time как pk Я не могу добавить две смены билетов одновременно.

Что я могу сделать?

2 ответа

Решение

Ты прав. Это известная проблема. Таким образом, единственными решениями являются хаки (вроде).

Ваш лучший вариант - использовать django-Composp. Недостатки в том, что он не поддерживает отношения модели, поэтому вы не сможете перейти к каким-либо отношениям из вашей составной модели ПК. Однако, глядя на вашу модель TicketChange, это не кажется проблемой (если только у вас нет больше моделей, связанных с этой).

Другой вариант - добавить столбец id вручную (и обязательно применить любые дополнительные изменения к базе данных), создав тем самым новый первичный ключ с одним столбцом. Третий вариант (и то, что я, вероятно, сделал бы), очень похожий на последний, но более чистый, - это создать новую базу данных с нуля, а затем заполнить ее сценарием, извлекая данные из существующей устаревшей базы данных.

Извините, у меня нет лучшего решения для вас, так оно и есть. Legacy dbs и django - это всегда головная боль, я сам прошел через некоторые похожие процессы. Надеюсь это поможет!

Это пример использования, который Django ORM просто не поддерживает. Если вы можете изменить схему базы данных, добавьте дополнительный столбец, который будет служить первичным ключом для Django: целочисленное поле с AUTO_INCREMENT (MySQL) или SERIAL (PostgreSQL). Он не должен нарушать работу других приложений, использующих таблицу, поскольку он будет управляться вашей базой данных при добавлении новых записей. Вы все еще можете использовать фактический первичный ключ при выполнении запросов через ORM:

ticket_change = TicketChange.objects.get(ticket=1234, time=5678, field='myfield')

Если вы хотите указать собственный первичный ключ, укажите primary_key=True в одном из ваших полей. Если Django увидит, что вы явно установили Field.primary_key, он не будет добавлять столбец автоматического идентификатора. Каждая модель требует, чтобы только одно поле имело primary_key=True (либо явно объявлено, либо добавлено автоматически).

https://docs.djangoproject.com/en/3.1/topics/db/models/#automatic-primary-key-fields

Другие вопросы по тегам