【问题标题】:How to use a custom Oracle sequence for Django Model PK?如何为 Django Model PK 使用自定义 Oracle 序列?
【发布时间】:2016-12-12 14:49:28
【问题描述】:

我正在将 Django 与现有 Oracle 数据库中的一个表集成,该数据库已经创建了一个序列并定义了它的 PK(数字)。我想要实现的是能够使用当前定义的序列为该表创建新行。我该怎么做?

【问题讨论】:

    标签: django oracle orm primary-key


    【解决方案1】:

    我根据this gist解决了这个问题,把id改成pk符号,这样就可以通用了:

    # your_app/models.py
    
    def update_pk(func):
    '''A decorator for pulling a data objects PK value out of a
       user-defined sequence.  This gets around a limitation in 
       django whereby we cannot supply our own sequence names.'''
    
        def decorated_function(*args):
            # Grab a reference to the data object we want to update.
            data_object = args[0]
    
            # Only update the PK if there isnt one yet.
            if data_object.pk is None:
                # Construct the new sequence name based on the tables meta data. This might be different depending on your needs
                sequence_name = 'seq_%s' % data_object._meta.db_table
    
                # Query the database for the next sequence value.
                from django.db import connection
                cursor = connection.cursor()
                cursor.execute("SELECT %s.nextval FROM DUAL;" % (sequence_name))
                row = cursor.fetchone()
    
                # Update the data objects PK with the returned sequence value.
                data_object.pk = row[0]
    
             # Execute the function were decorating.
             return func(*args)
    
        return decorated_function
    
    
    # Example model using the decorator to grab the PK.
    class FAQ(models.Model):
        id = models.IntegerField(primary_key=True)
        category = models.ForeignKey(FAQCategory)
        question = models.CharField(maxlength=255)
        answer = models.TextField()
        published = models.BooleanField(default=False)
        list_ordering = models.FloatField(max_digits=6, decimal_places=2, default=9999)
    
        def __str__(self):
            return self.question
    
        @update_pk
        def save(self):
            # Now actually save the object.
            super(FAQ, self).save()
    
        class Meta:
            db_table = 'faqs'
    

    【讨论】:

      【解决方案2】:

      我上周刚刚遇到这个问题。我的表在 Meta 中是用managed = false 定义的,并且使用了一个 Oracle 序列来提供主键值。要告诉 Django 在保存行后获取键值,请将列声明为 AutoField:

      surrogate_id = models.AutoField(primary_key=True,blank=True)
      

      【讨论】:

      • 如何声明用于填充字段的序列?
      • Adam,使用 Django 托管表,框架将在 Oracle 中创建并链接所需的序列。无需单独编码。我的建议仅适用于已经有序列设置的非托管表。
      • 我的问题更多的是“使用非托管表,如何生成新的序列值并将它们输入。”到目前为止,我已经看到人们使用插入触发器来更新序列中的列,但我希望在 django 中看到一些更好的方法。
      • 哦,所以您将 ID 和序列添加到现有表中。这有点不符合我的经验。
      猜你喜欢
      • 1970-01-01
      • 2014-03-01
      • 1970-01-01
      • 2018-12-25
      • 2016-11-11
      • 2011-03-21
      • 2014-10-05
      • 2017-05-19
      • 2016-09-14
      相关资源
      最近更新 更多