如何确保Django使用默认的“ now()”为“带时区的时间戳”生成postgres表架构

时间:2018-08-25 08:27:38

标签: python django postgresql

我有以下Django数据模型

class ApiLog(models.Model):
    name = models.TextField(blank=False, null=False)
    ts = models.DateTimeField(default=timezone.now, blank=False, null=False)
    ip_address = models.GenericIPAddressField(blank=True, null=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

以数据库结尾

django=# \d+ users_apilog
                                                           Table "public.users_apilog"
   Column   |           Type           | Collation | Nullable |                 Default                  | Storage  | Stats target | Description
------------+--------------------------+-----------+----------+------------------------------------------+----------+--------------+-------------
 id         | integer                  |           | not null | nextval('users_apilog_id_seq'::regclass) | plain    |              |
 name       | text                     |           | not null |                                          | extended |              |
 ts         | timestamp with time zone |           | not null |                                          | plain    |              |
 ip_address | inet                     |           |          |                                          | main     |              |
 user_id    | integer                  |           | not null |                                          | plain    |              |
Indexes:
    "users_apilog_pkey" PRIMARY KEY, btree (id)
    "users_apilog_user_id_2eb2b1cf" btree (user_id)
Foreign-key constraints:
    "users_apilog_user_id_2eb2b1cf_fk_users_user_id" FOREIGN KEY (user_id) REFERENCES users_user(id) DEFERRABLE INITIALLY DEFERRED

因此,该表也将由非Django应用访问。我需要确保自动时间戳生成(对于列ts)完全由postgres处理,而不是由python处理。


我不希望有

   Column   |           Type           | Collation | Nullable | Default | Storage | Stats target | Description
------------+--------------------------+-----------+----------+---------+---------+--------------+-------------
 ts         | timestamp with time zone |           | not null |         | plain   |              |

我希望有

   Column   |           Type           | Collation | Nullable | Default | Storage | Stats target | Description
------------+--------------------------+-----------+----------+---------+---------+--------------+-------------
 ts         | timestamp with time zone |           | not null | now()   | plain   |              |

我尝试了其他技术,例如auto_now=Trueauto_now_add=True,...

但是,它们都不产生我想要的表模式。通过使用以下任何内容,生成的表架构的default列仍为空。

  • default=timezone.now
  • auto_now=True
  • auto_now_add=True

1 个答案:

答案 0 :(得分:1)

因此,如今使用docker是很常见的。我将基于docker开发环境演示如何解决该问题。

步骤0:确保您已经提交了生成的0001_initial.py

步骤1:生成空的迁移文件

docker-compose run --rm -v %cd%/django:/app -w /app django /app/manage.py makemigrations users --empty -n alter_ts_default_to_now

步骤2:在迁移文件中使用原始SQL

# Generated by Django 2.1 on 2018-08-25 09:27

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('users', '0001_initial'),
    ]

    operations = [
        migrations.RunSQL(
            "ALTER TABLE users_apilog ALTER COLUMN ts SET DEFAULT now()",
        )    
    ]

第3步:再次运行迁移

#!/bin/sh

python manage.py makemigrations users

python manage.py makemigrations

python manage.py migrate

echo "yes" | python manage.py collectstatic

exec "$@"