最近在折腾greenplum,遇到一个蛋疼的问题,那就是获取表结构,也就是建表语句。大家都知道在MySQL里面是非常easy的,show create table table_name 就搞定了,在gpdb里面就没这么容易,在查询大量资料以后终于找到了方法。那就是自己定义一个函数去获取,函数中可以嵌套python代码,非常的方便。但是资料中的代码有大量错误,在经过几番调试以后终于可以使用了。

如果没有这个函数其实也可以获取表结构,那就是只能导出这个表的结构进行查看了。导出表结构的命令是:

pg_dump -s --table=tb1_partition_range_yyyymmdd testdb > tb1_partition_range_yyyymmdd.sql

查看表结构:

[gpadmin@mdw ~]$ cat tb1_partition_range_yyyymmdd.sql
--
-- Greenplum Database database dump
-- SET statement_timeout = ;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = off;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET escape_string_warning = off; SET search_path = public, pg_catalog; SET default_tablespace = ''; SET default_with_oids = false; --
-- Name: tb1_partition_range_yyyymmdd; Type: TABLE; Schema: public; Owner: gpadmin; Tablespace:
-- CREATE TABLE tb1_partition_range_yyyymmdd (
id numeric,
yyyymmdd date
)
WITH (appendonly=true, compresslevel=) DISTRIBUTED BY (id) PARTITION BY RANGE(yyyymmdd)
(
PARTITION p20120811 START ('2012-08-11'::date) END ('2012-08-12'::date) WITH (tablename='tb1_partition_range_yyyymmdd_1_prt_p20120811', orientation=row , appendonly=true, compresslevel= ),
PARTITION p20120812 START ('2012-08-12'::date) END ('2012-08-13'::date) WITH (tablename='tb1_partition_range_yyyymmdd_1_prt_p20120812', orientation=row , appendonly=true, compresslevel= )
); ALTER TABLE public.tb1_partition_range_yyyymmdd OWNER TO gpadmin; --
-- Name: idx_yyyymmdd; Type: INDEX; Schema: public; Owner: gpadmin; Tablespace:
-- CREATE INDEX idx_yyyymmdd ON tb1_partition_range_yyyymmdd USING btree (yyyymmdd); --
-- Greenplum Database database dump complete
--

还有一种方法就是\d table_name查看。这个只能查看字段信息啥的。

testdb=# \d+ tb1_partition_range_yyyymmdd
Append-Only Table "public.tb1_partition_range_yyyymmdd"
Column | Type | Modifiers | Storage | Description
----------+---------+-----------+---------+-------------
id | numeric | | main |
yyyymmdd | date | | plain |
Compression Type: zlib
Compression Level: 5
Block Size: 32768
Checksum: t
Indexes:
"idx_yyyymmdd" btree (yyyymmdd)
Child tables: tb1_partition_range_yyyymmdd_1_prt_p20120811,
tb1_partition_range_yyyymmdd_1_prt_p20120812
Has OIDs: no
Options: appendonly=true, compresslevel=5
Distributed by: (id)
Partition by: (yyyymmdd) testdb=#

总体来说还是不太方便,下面创建一个自定义的函数进行查看:

1. 创建语言

CREATE PROCEDURAL LANGUAGE plpythonu;

2. 创建函数(代码如下):

vim get_table_structure.sql
create or replace function get_table_structure(tablename text)
returns text
as $$
try:
table_name = tablename.lower().split('.')[]
talbe_schema=tablename.lower().split('.')[]
except (IndexError):
return 'Please in put "tableschema.table_name"'
get_table_oid="select oid,reloptions,relkind from pg_class where oid='%s'::regclass"%(tablename)
try:
rv_oid=plpy.execute(get_table_oid,5)
if not rv_oid:
return 'Did not find any relation named"'+tablename +'".'
except (Error):
return 'Did not find any relation named"'+tablename +'".'
table_oid=rv_oid[]['oid']
rv_reloptions=rv_oid[]['reloptions']
rv_relkind=rv_oid[]['relkind']
create_sql="";
table_kind='table';
if rv_relkind !='r' and rv_relkind !='v':
plpy.error('%s is not table or view'%(tablename));
elif rv_relkind=='v':
get_view_def="select pg_get_viewdef(%s,'t') as viewdef;" % (table_oid)
rv_viewdef=plpy.execute(get_view_def);
create_sql='create view %s as \n' % (tablename)
create_sql += rv_viewdef[]['viewdef']+'\n';
table_kind='view'
else:
get_columns="select a.attname,pg_catalog.format_type(a.atttypid,a.atttypmod),\
(select substring(pg_catalog.pg_get_expr(d.adbin,d.adrelid) for 128) \
from pg_catalog.pg_attrdef d where d.adrelid=a.attrelid and d.adnum=a.attnum and a.atthasdef) \
as default,a.attnotnull as isnull from pg_catalog.pg_attribute \
a where a.attrelid= %s and a.attnum >0 and not a.attisdropped order by a.attnum;" % (table_oid);
rv_columns=plpy.execute(get_columns) get_table_distribution1="select attrnums from pg_catalog.gp_distribution_policy t where localoid = '" + table_oid + "' "
rv_distribution1=plpy.execute(get_table_distribution1,500)
rv_distribution2=''
if rv_distribution1 and rv_distribution1[]['attrnums']:
get_table_distribution2="select attname from pg_attribute where attrelid='"+table_oid+"' and attnum in (" + str(rv_distribution1[]['attrnums']).strip('{').strip('}').strip('[').strip(']')+")"
rv_distribution2=plpy.execute(get_table_distribution2,500) create_sql='create table %s (\n' % (tablename)
get_index="select pg_get_indexdef(indexrelid) as indexdef from pg_index where indrelid=%s" % (table_oid);
rv_index=plpy.execute(get_index); get_parinfo1="select attname as columnname from pg_attribute where attnum =(select paratts[] from pg_partition where parrelid=%s) and attrelid=%s;"%(table_oid,table_oid);
get_parinfo2=""" select pp.parrelid,prl.parchildrelid,case when pp.parkind='h'::"char" then 'hash'::text when pp.parkind='r'::"char" then 'range'::text when pp.parkind='l'::"char" then 'list'::text else null::text end as partitiontype,pg_get_partition_rule_def(prl.oid,true) as partitionboundary from pg_partition pp,pg_partition_rule prl where pp.paristemplate=false and pp.parrelid = %s and prl.paroid = pp.oid order by prl.parname; """ % (table_oid)
v_par_parent=plpy.execute(get_parinfo1);
v_par_info=plpy.execute(get_parinfo2);
max_column_len=10
max_type_len=4
max_modifiers_len=4
max_default_len=4
for i in rv_columns:
if i['attname']:
if max_column_len < i['attname'].__len__():
max_column_len=i['attname'].__len__()
if i['format_type']:
if max_type_len < i['format_type'].__len__():
max_type_len=i['format_type'].__len__()
if i['default']:
if max_type_len < i['default'].__len__():
max_default_len=i['default'].__len__()
first=True
for i in rv_columns:
if first==True:
split_char=' ';
first=False
else:
split_char=',';
if i['attname']:
create_sql += " " + split_char + i['attname'].ljust(max_column_len+6)+''
else:
create_sql += "" + split_char + ' '.ljust(max_column_len+6)
if i['format_type']:
create_sql += ' ' + i['format_type'].ljust(max_type_len +2)
else:
create_sql += ' ' + ' '.ljust(max_type_len+2)
if i['isnull'] and i['isnull']:
create_sql += ' ' + ' not null '.ljust(8)
if i['default']:
create_sql += ' default ' + i['default'].ljust(max_default_len+6)
create_sql += "\n"
create_sql += ")" if rv_reloptions:
create_sql +=" with ("+str(rv_reloptions).strip('{').strip('}').strip('[').strip(']') +")\n"
create_sql = create_sql.replace("'",'')
if rv_distribution2:
create_sql += 'Distributed by ('
for i in rv_distribution2:
create_sql += i['attname'] + ','
create_sql =create_sql.strip(',')+')'
elif rv_distribution1:
create_sql += 'Distributed randomly\n'
if v_par_parent:
partitiontype=v_par_info[0]['partitiontype'];
create_sql +='\nPARTITION BY '+ partitiontype + "("+v_par_parent[0]['columnname']+")\n(\n";
for i in v_par_info:
create_sql +=" " +i['partitionboundary']+',\n';
create_sql=create_sql.strip(',\n');
create_sql+="\n)"
create_sql+=";\n\n"
for i in rv_index:
create_sql += i['indexdef']+';\n' get_table_comment="select 'comment on %s %s is '''|| COALESCE (description,'')|| '''' as comment from pg_description where objoid=%s and objsubid=0;" % (table_kind,tablename,table_oid)
get_column_comment="select 'comment on column %s.'||b.attname ||' is ''' || COALESCE(a.description,'')|| ''' ' as comment from pg_catalog.pg_description a,pg_catalog.pg_attribute b where objoid=%s and a.objoid=b.attrelid and a.objsubid=b.attnum;" % (tablename,table_oid)
rv_table_comment=plpy.execute(get_table_comment);
rv_column_comment=plpy.execute(get_column_comment); for i in rv_table_comment:
create_sql += i['comment']+';\n'
for i in rv_column_comment:
create_sql +=i['comment']+';\n'
return create_sql; $$ LANGUAGE plpythonu;

3. 进行测试

testdb=# SELECT get_table_structure('public.tb1_partition_range_yyyymmdd');
get_table_structure
-------------------------------------------------------------------------------------------------------------------
create table public.tb1_partition_range_yyyymmdd (
id numeric
,yyyymmdd date
) with (appendonly=true, compresslevel=5)
Distributed by (id)
PARTITION BY range(yyyymmdd)
(
PARTITION p20120811 START ('2012-08-11'::date) END ('2012-08-12'::date) WITH (appendonly=true, compresslevel=5),
PARTITION p20120812 START ('2012-08-12'::date) END ('2012-08-13'::date) WITH (appendonly=true, compresslevel=5)
); CREATE INDEX idx_yyyymmdd ON tb1_partition_range_yyyymmdd USING btree (yyyymmdd); (1 row)

参考资料:

《greenplum 企业应用实战》

Greenplum获取表结构的更多相关文章

  1. Sql中获取表结构(字段名称,类型,长度,说明)

    Sql中获取表结构(字段名称,类型,长度,说明) SELECT TableName = OBJECT_NAME(c.object_id), ColumnsName = c.name, Descript ...

  2. MySql 、Oracle 获取表结构和字段信息

    1.MySql获取表结构信息 SELECT TABLE_NAME, TABLE_COMMENT FROM information_schema.`TABLES` WHERE TABLE_SCHEMA ...

  3. 【Navicat】获取表结构的DDL语句以及获取更新表字段的操作的DDL

    1.获取表结构的DDL语句 2.获取修改表结构某一字段的DDL语句  设计表-修改表字段(记住不要保存)-SQL预览

  4. Oracle安装、Navicat for Oracle、JDBCl连接、获取表结构

    Oracle安装 Navicat for Oracle配置 Oracle JDBC连接(增删改查) Oracle安装 环境windows 7 64位 安装版本:oracle 11g(64位) 下载地址 ...

  5. SqlServer获取表结构语句

    --sql server 2005-- 1. 表结构信息查询 -- ================================================================== ...

  6. Oracle 获取表结构信息

    通过Oracle中的user_tab_cols, user_col_comments, user_constraints, user_cons_columns表联合查询. user_tab_cols用 ...

  7. sql server 获取表结构和记录数

    表结构 then d.name else null end) 表名, a.colorder 字段序号,a.name 字段名, ( then '√'else '' end) 标识, (case when ...

  8. mssql 获取表结构信息

    SELECT (case when a.colorder=1 then d.name else null end) 表名, a.colorder 字段序号,a.name 字段名, (case when ...

  9. SQL 获取表结构

    select [表名]=c.Name, [表说明]=isnull(f.[value],''), [列序号]=a.Column_id, [列名]=a.Name, [列说明]=isnull(e.[valu ...

随机推荐

  1. loadrunner参数化excel数据

    LR参数化数据源Oracle,MSSQL,Excel参数化的方法: 重点介绍excel数据参数化的方法: 1.首先创建excel表格: 注意要写列明   2.创建excel表连接:   参数化完成后, ...

  2. linux服务器init 5启动图形界面,报错Retrigger failed udev events

    今天因工作需要开启linux系统的桌面环境,使用startx未成功,报如下错误: [root@ /]# startx xauth: creating new authority xinit: No s ...

  3. SpringMyBatis解析1-使用示例

    MyBatis使用介绍 MyBatis的详细使用介绍  http://www.cnblogs.com/xrq730/category/796495.html 建立PO public class Per ...

  4. node.js整理 01代码的组织和部署

    模块 require(函数) 用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对象. 模块名可使用相对路径(以./开头),或者是绝对路径(以/或C:之类的盘符开头:注意单个模块名默 ...

  5. Swift3.0语言教程字符串与文件的数据转换

    Swift3.0语言教程字符串与文件的数据转换 Swift3.0语言教程字符串与文件的数据转换,如果想要对字符串中的字符进行永久保存,可以将字符串中的字符写入到文件中.当然,开发者也可以将写入的内容进 ...

  6. 浩瀚移动POS收银开单扫描解决方案PDA仓储系统,无线批发,移动批发,无线POS,无线销售APP-车销管理PDA

    适用范围 各种业态的批发商铺.批发市场.订货会.展销会.配送中心仓库…… 产品简介 随着移动技术与智能PDA设备的迅猛发展,中国已经跨步进入移动信息化社会.移动商务是移动信息社会的重要载体与形式,它开 ...

  7. 从Sql server 2008获取表字段属性信息,注释信息

    select   b.[value] from sys.columns a left join sys.extended_properties b on a.object_id=b.major_id  ...

  8. [TJOI2016&HEOI2016]

    很有意思.是因为排序那道题才听闻今年tjoi2016的. 题是好题!先把它刷完再去把zhihu look through一遍. bzoj4552 以后看到什么做不出的题,看看能否写二分!!!!写二分! ...

  9. stl(set+stack) LA 3634 The SetStack Computer

    题目传送门 题意:给一些对集合的操作,询问每一次操作后栈顶的集合元素个数 分析:首先{}是空的,每一次add时候,{} -> { {} }变成了有一个元素的集合,利用set和stack,map容 ...

  10. iOS Aspect Fit,Aspect Fill,Scale To Fill

    Scale:拉伸图片,图片变形. Aspect:图片长宽的保持比例,图片不变形. Aspect Fill(常用):图像充满容器.以长宽中小的参数为限制. Aspect Fit:图像在容器中完整显示.以 ...