无法使用Redshift目录查询的输出

时间:2016-02-26 05:53:45

标签: amazon-redshift

我在使用针对Redshift目录表的查询时遇到各种问题。

为了说明,以下工作:

select "table_name"::text as "table"
from "information_schema"."tables"
where table_schema not like 'pg_%' and table_schema != 'information_schema'

以及以下作品:

create view works as 
select "table_name"::text as "table"
from "information_schema"."tables"
where table_schema not like 'pg_%' and table_schema != 'information_schema'

但以下失败:

create table fails as
select "table_name"::text as "table"
from "information_schema"."tables"
where table_schema not like 'pg_%' and table_schema != 'information_schema'

使用:

[SQL]create table fails as
select "table_name"::text as "table"
from "information_schema"."tables"
INFO:  Function "has_table_privilege(oid,text)" not supported.
INFO:  Function "has_table_privilege(oid,text)" not supported.
INFO:  Function "has_table_privilege(oid,text)" not supported.
INFO:  Function "has_table_privilege(oid,text)" not supported.
INFO:  Function "has_table_privilege(oid,text)" not supported.
INFO:  Function "has_table_privilege(oid,text)" not supported.
INFO:  Function "has_table_privilege(oid,text)" not supported.
[Err] ERROR:  Specified types or functions (one per INFO message) not supported on Redshift tables.

http://docs.aws.amazon.com/redshift/latest/dg/c_join_PG.html我读了

If you write a join query that explicitly or implicitly references a column that has an unsupported data type, the query returns an error.

这是否意味着在基于对目录表的选择的创建表中(即使我将奇怪的字段类型转换为文本)在引擎盖下Redshift正在进行连接和奇怪的东西,这意味着我不能这样做?

创建表是问题的一种表现形式。另一个是我无法根据目录查询卸载视图或任何内容。例如。以下内容也会因上述类似的错误消息而失败。

unload ('select * from "works"') to 's3://etc'

目前,我可以使用此数据的唯一方法是从外部程序发出查询,然后让该外部程序将结果集手动写回表。即无法从数据库中完成。

有人有另一种解决方案吗?

1 个答案:

答案 0 :(得分:3)

我遇到过类似的问题,我不确定原因的细节,但找到了解决方法。

不要在information_schema中查找值,而是尝试在pg_catalog表中查找关系和属性名称。

例如,以下查询提供特定表的列名:

SELECT attname::text FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '<your_table_name>') AND attname NOT IN ('insertxid', 'deletexid', 'oid', 'tableoid', 'xmin', 'cmin', 'xmax', 'cmax', 'ctid');

此查询可用于CREATE TABLE语句:

CREATE TABLE consumer_person_dated_attr_types AS
SELECT attname::text FROM pg_attribute 
WHERE attrelid = (SELECT oid FROM pg_class 
    WHERE relname = '<your_table>') AND attname NOT IN ('oid', 'tableoid', 'xmin', 'cmin', 'xmax', 'cmax', 'ctid'
);

类似地,以下查询创建一个表,其中包含一个表名列,另一个表包含模式名称:

CREATE TABLE tmp_table_names AS
SELECT relname::text, nspname::text
FROM pg_class c
JOIN pg_namespace n
ON n.oid = c.relnamespace
WHERE nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');

请注意,目录表提供了比information_schema更多的系统级详细信息。例如,每个表都有上面查询返回的内部系统列,因此如果您只想要DDL中定义的列的列名,则需要排除内部system columns。除了列出的列之外,RedShift还从上面的查询中返回deletexid和insertxid,因此也应该排除这些列。查询表列表也是如此(即返回的系统模式很多)。

我怀疑这与列的数据类型有关。 information_schema中许多列的数据类型是'sql_identifier',JDBC类型为'OTHER'(在SQLWorkbenchJ中查看时),而类似列的pg_catalog表的数据类型为'name',JDBC类型为'VARCHAR'。