django迁移中的自定义sql不起作用

时间:2017-02-17 20:49:50

标签: django postgresql django-migrations

我正在尝试在迁移中运行自定义SQL。这就是它的样子:

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.RunSQL(
            "SET timezone TO 'UTC'",
        ),
    ]

当我用

运行它时
  

./ manage.py migrate helper

我可以在日志中看到运行SQL命令:

[17/Feb/2017 20:37:37] DEBUG [django.db.backends.schema:103] SET timezone TO 'UTC'; (params None)
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.000) SET timezone TO 'UTC';

但是当我在数据库中检查它时,仍然说时区是本地时间:

gdp=# show timezone;
 TimeZone  
-----------
 localtime
(1 row)

如果我手动运行相同的命令,它可以正常工作:

gdp=# SET timezone TO 'UTC';
SET
gdp=# 
gdp=# show timezone;
 TimeZone 
----------
 UTC
(1 row)

Django版本:1.10.5

PostgreSQL版本:9.5.5

完整日志:

[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.591) CREATE EXTENSION IF NOT EXISTS postgis; args=None
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.002) 
            SELECT c.relname, c.relkind
            FROM pg_catalog.pg_class c
            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
            WHERE c.relkind IN ('r', 'v')
                AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
                AND pg_catalog.pg_table_is_visible(c.oid); args=None
[17/Feb/2017 20:37:37] DEBUG [django.db.backends.schema:103] CREATE TABLE "django_migrations" ("id" serial NOT NULL PRIMARY KEY, "app" varchar(255) NOT NULL, "name" varchar(255) NOT NULL, "applied" timestamp with time zone NOT NULL); (params None)
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.014) CREATE TABLE "django_migrations" ("id" serial NOT NULL PRIMARY KEY, "app" varchar(255) NOT NULL, "name" varchar(255) NOT NULL, "applied" timestamp with time zone NOT NULL); args=None
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.001) 
            SELECT c.relname, c.relkind
            FROM pg_catalog.pg_class c
            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
            WHERE c.relkind IN ('r', 'v')
                AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
                AND pg_catalog.pg_table_is_visible(c.oid); args=None
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
[17/Feb/2017 20:37:37] DEBUG [django.db.backends.schema:103] SET timezone TO 'UTC'; (params None)
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.000) SET timezone TO 'UTC'; args=None
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.000) 
            SELECT c.relname, c.relkind
            FROM pg_catalog.pg_class c
            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
            WHERE c.relkind IN ('r', 'v')
                AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
                AND pg_catalog.pg_table_is_visible(c.oid); args=None
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.000) INSERT INTO "django_migrations" ("app", "name", "applied") VALUES ('helper', '0001_initial', '2017-02-17T20:37:37.272476+00:00'::timestamptz) RETURNING "django_migrations"."id"; args=(u'helper', u'0001_initial', datetime.datetime(2017, 2, 17, 20, 37, 37, 272476, tzinfo=<UTC>))
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.001) 
            SELECT c.relname, c.relkind
            FROM pg_catalog.pg_class c
            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
            WHERE c.relkind IN ('r', 'v')
                AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
                AND pg_catalog.pg_table_is_visible(c.oid); args=None
[17/Feb/2017 20:37:37] DEBUG [django.db.backends:90] (0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()

编辑

我有这些设置:

USE_TZ = True 
TIME_ZONE = 'UTC' 

但是这个Django使用我当地的时区将日期时间保存到Postgres,就像这个'2016-09-12T08:06:45-04:00'。当我通过Django查询数据库时它确实将它转换回UTC但我想在Postgres中使用'clean'datetime,就像这样'2016-09-12T12:06:45 + 00'。

2 个答案:

答案 0 :(得分:1)

我在PostgreSQL文档8.5.3. Time Zones中找到了我的问题的答案:

  

SQL命令SET TIME ZONE设置会话的时区。

我能够通过在 postgresql.conf 中设置时区来解决这个问题(对我而言,它位于 /etc/postgresql/9.5/main 中)。

答案 1 :(得分:0)

当您使用DateTimeField时,Django会设置自己的时区。在您的settings.py中,您应该找到以下设置:

TIME_ZONE='UTC'

您可以将此设置为None来禁用djangos timezone-usage。但是,我相信这只会将所有DateTimeField值转换为没有时区的值。 (没试过)

我建议在任何情况下都使用djangos TIME_ZONE设置,因为它可以确保所有数据库的一致性。