9

It seems like default value on columns is only on the ORM layer, and is not actually setting a default value in the DB. At the same time, the ID key for example has a default modifier in the database, which tells me it is possible to do that, but not sure how?

Example code:

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

creates the following table:

  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

Is there a way to have the migration set default current_timestamp in the created_at modifiers? If not, is there a way to pass in raw SQL migrations? I need it because the database is used by other processes (e.g. batch processes) which I don't want to have to enforce things like default values on the application layer.

1
  • Going to try to override apply method in models.Migration and have it run raw sql. Commented Jan 24, 2015 at 20:58

2 Answers 2

8

I would put your code in a RunSQL operation, something like:

class Migration(migrations.Migration):

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

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

I think this approach is cleaner than trying to override apply(). The API makes it easy to add the SQL for the reverse operation, and because the migration infrastructure understands the semantics of RunSQL it might be able to make better decisions. (For example, it knows not to squash migrations across a migration that has a RunSQL operation.)

Sign up to request clarification or add additional context in comments.

1 Comment

0

This worked for me. I still would like to know if there are cleaner solutions:

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.