Django с устаревшей базой данных - как работать с последовательностями БД?
Учитывая таблицу базы данных, которая была создана с помощью этого запроса SQL:
CREATE TABLE Bill
(
Time DATE NOT NULL ,
Address VARCHAR2 (60) NOT NULL ,
ID NUMBER NOT NULL
) ;
ALTER TABLE Bill ADD CONSTRAINT Bill_PK PRIMARY KEY ( ID ) ;
CREATE SEQUENCE Bill_ID_SEQ START WITH 1 NOCACHE ORDER ;
CREATE OR REPLACE TRIGGER Bill_ID_TRG BEFORE
INSERT ON Paragony FOR EACH ROW BEGIN :NEW.ID := Bill_ID_SEQ.NEXTVAL;
END;
Я должен использовать его с Django ORM, поэтому я запустил inspectdb
команда. Это автоматически сгенерированный код:
class Bill(models.Model):
time = models.DateField()
address = models.CharField(max_length=60)
id = models.IntegerField(primary_key=True)
class Meta:
managed = False
db_table = 'bill'
После сохранения в приложение models.py
файл и запущенные миграции все было хорошо. Я мог читать БД, как будто она была создана с использованием ORM. Однако возникла проблема с созданием строк в таблице Билла.
Это простая форма для модели Билла:
class BillForm(ModelForm):
class Meta:
model = Bill
fields = ('time', 'address')
Проблема в том, что я не могу получить идентификатор, сгенерированный с помощью последовательности DB. Добавление id
поле в форму не будет работать, потому что мы должны сгенерировать его с помощью кода и затем передать в качестве аргумента. Даже если база данных создаст другой идентификатор, который будет невозможно получить без необработанных запросов.
1 ответ
Решение действительно простое. Мы должны удалить id
поле из модели Билла:
class Bill(models.Model):
time = models.DateField()
address = models.CharField(max_length=60)
# Remove 'id' field so the ORM can work properly.
# id = models.IntegerField(primary_key=True)
class Meta:
managed = False
db_table = 'bill'
Таким образом, Django ORM может выполнить всю тяжелую работу и правильно использовать устаревшие последовательности базы данных. Объекты Bill теперь можно создавать с помощью BillForm, и у них будут правильные идентификаторы.