【问题标题】:Django with legacy database - how to work with DB sequences?带有遗留数据库的 Django - 如何使用数据库序列?
【发布时间】:2017-01-11 13:01:00
【问题描述】:

给定一个使用此 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 创建数据库一样读取数据库。但是在 Bill 表中创建行时出现问题。

Bill 模型的简单形式:

class BillForm(ModelForm):

    class Meta:
        model = Bill
        fields = ('time', 'address')

问题是我无法检索使用 DB 序列生成的 ID。将 id 字段添加到 Form 将不起作用,因为我们必须使用代码生成它,然后作为参数传递。即使数据库会创建不同的 ID,如果没有原始查询,这些 ID 将无法检索。

【问题讨论】:

    标签: django django-models legacy-database database-sequence


    【解决方案1】:

    解决方案非常简单。我们必须从 Bill 模型中删除 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 可以完成所有艰苦的工作并正确使用遗留数据库序列。现在可以使用 BillForm 创建 Bill 对象,并且它们将具有正确的 ID。

    【讨论】:

      猜你喜欢
      • 2017-03-19
      • 1970-01-01
      • 2011-01-17
      • 2013-08-07
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多