Skip to main content

支持 Django 中的 PostgreSQL 视图

项目描述

Postgres 的 SQL 视图

圈子CI

在 Django ORM 中添加对PostgreSQL 视图的一流支持

安装

通过 pip 安装:

pip install django-postgres-views

在 settings.py 中添加到已安装的应用程序:

INSTALLED_APPS = (
  # ...
  'django_postgres_views',
)

例子

from django.db import models

from django_postgres_views import view as pg


class Customer(models.Model):
    name = models.CharField(max_length=100)
    post_code = models.CharField(max_length=20)
    is_preferred = models.BooleanField(default=False)

    class Meta:
        app_label = 'myapp'

class PreferredCustomer(pg.View):
    projection = ['myapp.Customer.*',]
    dependencies = ['myapp.OtherView',]
    sql = """SELECT * FROM myapp_customer WHERE is_preferred = TRUE;"""

    class Meta:
      app_label = 'myapp'
      db_table = 'myapp_preferredcustomer'
      managed = False

注意重要的是,我们将 包含managed = False在MetaDjango 1.7 迁移中,因此不会尝试为此视图创建数据库表。

由此产生的 SQL 可能如下所示:

CREATE VIEW myapp_preferredcustomer AS
SELECT * FROM myapp_customer WHERE is_preferred = TRUE;

要创建所有视图,请运行python manage.py sync_postgres_views

您还可以指定字段名称,这些名称将映射到视图中的字段:

from django_postgres_views import view as pg


VIEW_SQL = """
    SELECT name, post_code FROM myapp_customer WHERE is_preferred = TRUE
"""


class PreferredCustomer(pg.View):
    name = models.CharField(max_length=100)
    post_code = models.CharField(max_length=20)

    sql = VIEW_SQL

用法

要映射到视图,只需扩展pg_views.view.View,将 SQL 分配给 sql参数并定义db_table. 您必须始终设置类managed = False 。Meta

可以通过多种方式创建视图:

  1. 定义要映射到 VIEW 输出的字段
  2. 定义描述 VIEW 字段的投影

定义字段

像使用任何 Django 模型一样定义字段:

from django_postgres_views import view as pg


VIEW_SQL = """
    SELECT name, post_code FROM myapp_customer WHERE is_preferred = TRUE
"""


class PreferredCustomer(pg.View):
    name = models.CharField(max_length=100)
    post_code = models.CharField(max_length=20)

    sql = VIEW_SQL

     元类:
      托管 =  False 
      db_table  =  'my_sql_view'

定义投影

django-postgres-views可以进行投影来确定它需要映射到哪些字段以进行视图。要使用它,请设置projection属性:

from django_postgres_views import view as pg


class PreferredCustomer(pg.View):
    projection = ['myapp.Customer.*',]
    sql = """SELECT * FROM myapp_customer WHERE is_preferred = TRUE;"""

    class Meta:
      db_table = 'my_sql_view'
      managed = False

这将占用所有字段myapp.Customer并将它们应用于 PreferredCustomer

特征

更新视图

有时您的模型会发生变化,您需要数据库视图来反映新数据。更新 View 逻辑就像修改底层 SQL 并运行一样简单:

python manage.py sync_postgres_views --force

这将强制更新与您的新 SQL 冲突的任何视图。

迁移

运行迁移时,我们将使用 postmigration信号自动同步您的新视图,如果您在任何时候想要覆盖此功能,您可以通过PGVIEW_SYNC_VIEW_PATH 使用自己的迁移命令添加完整路径来补充您自己的功能。

依赖项

您可以指定您依赖的其他视图。这可确保预先安装其他视图。使用依赖项还可以确保您的视图在使用sync_postgres_views --force.

注意:视图在 Django 应用程序迁移后同步,将模型添加到依赖项列表将导致同步失败。

例子:

from django_postgres_views import view as pg

class PreferredCustomer(pg.View):
    dependencies = ['myapp.OtherView',]
    sql = """SELECT * FROM myapp_customer WHERE is_preferred = TRUE;"""

    class Meta:
      app_label = 'myapp'
      db_table = 'myapp_preferredcustomer'
      managed = False

物化视图

Postgres 9.3 及更高版本支持物化视图 ,允许您缓存视图的结果,从而可能使它们加载得更快。

但是,您确实需要手动刷新视图。要自动执行此操作,您可以附加信号 并调用刷新函数。

例子:

from django_postgres_views import view as pg


VIEW_SQL = """
    SELECT name, post_code FROM myapp_customer WHERE is_preferred = TRUE
"""

class Customer(models.Model):
    name = models.CharField(max_length=100)
    post_code = models.CharField(max_length=20)
    is_preferred = models.BooleanField(default=True)


class PreferredCustomer(pg.MaterializedView):
    name = models.CharField(max_length=100)
    post_code = models.CharField(max_length=20)

    sql = VIEW_SQL


@receiver(post_save, sender=Customer)
def customer_saved(sender, action=None, instance=None, **kwargs):
    PreferredCustomer.refresh()

Postgres 9.4 及更高版本允许同时刷新物化视图,而不会阻塞读取,只要物化视图上存在唯一索引即可。要启用并发刷新,请指定可用作物化视图上唯一索引的列的名称。可以在物化视图的多个列上定义唯一索引。一旦启用,传递concurrently=True给模型的刷新方法将导致 postgres 并发执行刷新。(请注意,刷新方法本身会阻塞,直到刷新完成;当物化视图在另一个进程或线程中更新时,并发刷新最有用。)

例子:

from django_postgres_views import view as pg


VIEW_SQL = """
    SELECT id, name, post_code FROM myapp_customer WHERE is_preferred = TRUE
"""

class PreferredCustomer(pg.MaterializedView):
    concurrent_index = 'id, post_code'
    sql = VIEW_SQL

    name = models.CharField(max_length=100)
    post_code = models.CharField(max_length=20)


@receiver(post_save, sender=Customer)
def customer_saved(sender, action=None, instance=None, **kwargs):
    PreferredCustomer.refresh(concurrently=True)

自定义架构

您可以为视图定义任何您希望的表名。它们甚至可以存在于您自己的自定义 PostgreSQL 模式中。

from django_postgres_views import view as pg


class PreferredCustomer(pg.View):
    sql = """SELECT * FROM myapp_customer WHERE is_preferred = TRUE;"""

    class Meta:
      db_table = 'my_custom_schema.preferredcustomer'
      managed = False

同步监听器

django-postgres-views 0.0.1 增加了监听post_sync事件发生的能力。

view_synced

每次 VIEW 与数据库同步时触发。

提供参数:

  • sender- 查看课程
  • update- 视图是否要更新
  • force- 是否force通过
  • status- 创建视图的结果,例如EXISTS,FORCE_REQUIRED
  • has_changed- 视图是否必须改变

all_views_synced

在所有 Postgres VIEW 同步后发送。

提供参数:

  • sender- 总是None

下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

django-postgres-views-0.0.4.tar.gz (13.0 kB 视图哈希)

已上传 source

内置分布

django_postgres_views-0.0.4-py3-none-any.whl (13.7 kB 查看哈希)

已上传 py3