如何使用 django 1.7.3/postgres 迁移在数据库中设置默认列值?

Posted

技术标签:

【中文标题】如何使用 django 1.7.3/postgres 迁移在数据库中设置默认列值?【英文标题】:How to set default column value in the db using django 1.7.3/postgres migrations? 【发布时间】:2015-03-23 16:16:02 【问题描述】:

似乎列的默认值仅在 ORM 层上,实际上并未在数据库中设置默认值。同时,例如 ID 键在数据库中有一个默认修饰符,它告诉我可以这样做,但不确定如何?

示例代码:

class Host(models.Model):
    name = models.CharField(max_length=255, null=False)
    created_at = models.DateTimeField(default=datetime.now, blank=True)

创建下表:

  Column   |           Type           |                          Modifiers                          
------------+--------------------------+-------------------------------------------------------------
 id         | integer                  | not null default nextval('myapp_host_id_seq'::regclass)
 name       | character varying(255)   | not null
 created_at | timestamp with time zone | not null

有没有办法在created_at 修饰符中设置迁移集default current_timestamp?如果没有,有没有办法传入原始 SQL 迁移?我需要它,因为数据库被其他进程(例如批处理)使用,我不想在应用层强制执行诸如默认值之类的东西。

【问题讨论】:

将尝试覆盖 models.Migration 中的 apply 方法并让它运行原始 sql。 【参考方案1】:

这对我有用。我仍然想知道是否有更清洁的解决方案:

class Migration(migrations.Migration):

dependencies = [
    ('myapp', 'previous_migration'),
]

operations = []

def apply(self, project_state, schema_editor, collect_sql=False):
    cursor = connection.cursor()
    cursor.execute("alter table myapp_host alter column created_at set default current_timestamp")
    return super(Migration, self).apply(project_state, schema_editor, collect_sql)

【讨论】:

【参考方案2】:

我会将您的代码放在RunSQL operation 中,例如:

class Migration(migrations.Migration):

dependencies = [
    ('myapp', 'previous_migration'),
]

operations = [
    migrations.RunSQL("alter table myapp_host alter column created_at set default current_timestamp"),
]

我认为这种方法比尝试覆盖apply() 更干净。 API 使添加 SQL 以进行反向操作变得容易,并且由于迁移基础架构理解 RunSQL 的语义,它可能能够做出更好的决策。 (例如,它知道不会在具有 RunSQL 操作的迁移中压缩迁移。)

【讨论】:

+1 用于 RunSQL。我也推荐overriding the original migration using the state_operations parameter

以上是关于如何使用 django 1.7.3/postgres 迁移在数据库中设置默认列值?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用django session

Django:当我使用 django 表单时,如何实现这个 html 表单

django-1-新手如何使用django

如何仅使用 django 作为后端并使用 django-rest-framework 发布

如何使用WSGI部署Django

如何使用 Django 配置 Celery 守护进程