转储文件中视图的预定义的目的是什么

sme*_*fju 5 postgresql activerecord ruby-on-rails pg-dump

我正在处理的项目中,我们正在为Active Record转储器使用:sql架构格式(以支持触发器等更复杂的逻辑)。

我们有很多视图,并且我可以在database/structure.sql文件中看到其中一些具有带有的“预定义”架构,NULL例如:

CREATE VIEW public.my_view AS
  SELECT
    NULL::integer AS record_id,
    NULL::integer AS another_record_id,
    NULL::double precision AS some_field;
Run Code Online (Sandbox Code Playgroud)

然后,在数千行之后,使用以下命令添加定义:

CREATE OR REPLACE VIEW public.my_view AS
  -- actual query
Run Code Online (Sandbox Code Playgroud)

我在SQL查询中看不到架构“预定义”和定义之间对视图的任何引用。另外,还有其他立即创建的视图(没有该模式“ predefinition”)。

我在查看Active Record文档,但找不到任何提示。Rails pg_dump在后台使用,但我在pg_dump文档中也看不到任何相关内容。

为什么有些视图需要预先预定义架构,而另一些视图则不需要,即使在database/structure.sql文件中的预定义和实际定义之间没有引用它们时也是如此?使用其他结构(例如实体化视图等)时,是否可以防止某些竞赛条件?

Luk*_*der 3

这是因为视图可以具有如下循环依赖关系:

CREATE SCHEMA s;
CREATE OR REPLACE VIEW s.v AS SELECT 1 a;
CREATE OR REPLACE VIEW s.w AS SELECT a FROM s.v;
CREATE OR REPLACE VIEW s.v AS SELECT a FROM s.w;
Run Code Online (Sandbox Code Playgroud)

无法以这种形式查询这些视图。例如select * from s.w产生:

SQL 错误 [42P17]:错误:在关系“w”的规则中检测到无限递归

但运行以下pg_dump命令:

pg_dump -U postgres -d postgres -s -n s
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

CREATE SCHEMA s;

CREATE VIEW s.v AS
SELECT
    NULL::integer AS a;

CREATE VIEW s.w AS
 SELECT v.a
   FROM s.v;

CREATE OR REPLACE VIEW s.v AS
 SELECT w.a
   FROM s.w;
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,必须创建虚拟视图,因为s.vs.w无法访问创建时尚未存在的视图。

pg_dump.c您还可以在的createDummyViewAsClausefunction中找到此逻辑,其文档如下:

/*
 * Create a dummy AS clause for a view.  This is used when the real view
 * definition has to be postponed because of circular dependencies.
 * We must duplicate the view's external properties -- column names and types
 * (including collation) -- so that it works for subsequent references. [...]
 */
Run Code Online (Sandbox Code Playgroud)