我要做的是聚合来自所有租户/用户的所有数据,并从那里创建一个SQL视图。然而,租户的创建是动态创建的,但是放心,所有的表都是相同的。
我在这里要做的是首先使用此查询获取我数据库中的所有租户。
select distinct table_schema
from information_schema.tables
where table_schema not in ('pg_catalog', 'information_schema','public')
and table_schema not like 'pg_toast%'
我想做的是每一行,我会做一个工会。
类似这样的事情
(SELECT * FROM tenant1.ref_product)
UNION ALL(SELECT * FROM tenant2.ref_product)
UNION ALL(SELECT * FROM tenant3.ref_product)
这可能吗?
答案 0 :(得分:2)
你不能在一个命令中执行此操作,首先需要执行一个来构建所需的SELECT
语句,并复制其结果并执行它:
SELECT string_agg(
format('(SELECT * FROM %I.ref_product)', nspname),
' UNION ALL ')
FROM pg_namespace
WHERE nspname !~ '^(pg_.*|information_schema|public)$';
另一种选择是使用PL / pgSQL EXECUTE
命令,例如:
CREATE OR REPLACE FUNCTION ref_product()
RETURNS SETOF tenant1.ref_product
LANGUAGE plpgsql STABLE AS $$
DECLARE
v_cmd text;
BEGIN
SELECT string_agg(
format('(SELECT * FROM %I.ref_product)', nspname),
' UNION ALL ')
INTO v_cmd
FROM pg_namespace
WHERE nspname !~ '^(pg_.*|information_schema|public)$'
RETURN QUERY EXECUTE v_cmd;
END;
$$;
最后,如果您经常使用它,请考虑使用相同的表定义创建另一个模式(让我们说“tenant_all”),并使用PostgreSQL的INHERTIS
将所有其他表设置为它的子项。例如:
CREATE SCHEMA tenant_all;
CREATE TABLE tenant_all.ref_product(LIKE tenant1.ref_product);
ALTER TABLE tenant1.ref_product INHERIT (tenant_all.ref_product);
ALTER TABLE tenant2.ref_product INHERIT (tenant_all.ref_product);
ALTER TABLE tenant3.ref_product INHERIT (tenant_all.ref_product);
...
ALTER TABLE tenantN.ref_product INHERIT (tenant_all.ref_product);
通过这种方式,您可以简单地查询tennat_all.ref_product
,它就像您查询附加UNION ALL
的内容一样。
当然,在所有情况下,我都假设表格架构完全匹配。