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文件中的预定义和实际定义之间没有引用它们时也是如此?使用其他结构(例如实体化视图等)时,是否可以防止某些竞赛条件?
这是因为视图可以具有如下循环依赖关系:
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)
| 归档时间: |
|
| 查看次数: |
58 次 |
| 最近记录: |