2008-12-05 25 views
24

Tôi đang chạy một dự án trên cơ sở dữ liệu Postgres và cần truy xuất các nhận xét về các cột trong DB để được sử dụng làm tiêu đề bảng và như vậy. Tôi đã thấy rằng có một vài chức năng được xây dựng (pg_descriptioncol_description) nhưng tôi đã không thể tìm thấy ví dụ về cách sử dụng chúng và chơi xung quanh với chúng đã tỏ ra khá vô ích.Truy xuất nhận xét từ một DB PostgreSQL

Vì vậy, tôi đã tự hỏi liệu có ai có thể làm được điều này trước và nếu có, làm thế nào?

+0

PostgreSQL không phải là rất thân thiện, nhưng đó là vì mỗi người dùng có thư viện cá nhân (không chuẩn) của bạn ". Bên dưới một hàm ('rel_description') của thư viện của tôi, có thể giúp bạn. –

Trả lời

1

Ok, do đó, tôi đã làm việc nó ra đến mức độ ...

chọn col_description (bảng id, số cột) ...

ví dụ: chọn col_description (36698,2);

Điều đó có hiệu quả, nhưng có cách nào dễ hơn để thực hiện việc này có thể mang tất cả các nhận xét lên tất cả các cột và sử dụng tên bảng thay vì oid ???

11

Tất cả các tác phẩm của oid,

mat=> SELECT c.oid FROM pg_catalog.pg_class c WHERE c.relname = 'customers'; 
    oid 
------- 
23208 
(1 row) 

Bây giờ, tôi có oid cho bảng đó, vì vậy tôi có thể đặt câu hỏi:

mat=> select pg_catalog.obj_description(23208); 
    obj_description 
------------------- 
Customers 
(1 row) 

Sau đó, tôi có thể yêu cầu các mô tả về thứ tư cột:

mat=> select pg_catalog.col_description(23208,4); 
      col_description    
----------------------------------------- 
Customer codes, CHS, FACTPOST, POWER... 
(1 row) 

Nếu bạn muốn biết truy vấn nào psql chạy khi bạn làm \dt+ hoặc \d+ customers, chỉ cần chạy với -E.

+0

"obj_description (object_oid)" hiện không được chấp nhận, xem https://www.postgresql.org/docs/current/static/functions-info.html – alfonx

1

Cool, hoạt động để đưa ra một nhận xét duy nhất, nhưng có cách nào để hiển thị tất cả các nhận xét từ tất cả các cột mà không có nhiều câu lệnh chọn hoặc vòng lặp không?

Và làm thế nào để bạn khởi động này với một tuyên bố:

Nếu bạn muốn biết mà các truy vấn không psql chạy khi bạn làm \ dt + hoặc \ d + khách hàng, chỉ cần launche nó với -E.

Cảm ơn

0

Tôi hỏi a similar question about Postgresql comments tháng trước. Nếu bạn khai thác thông qua đó, bạn sẽ gặp một số mã Perl trên blog của tôi để tự động hóa quá trình trích xuất nhận xét.

Để rút khỏi các tên cột của một bảng, bạn có thể sử dụng giống như sau:

select 
    a.attname as "colname" 
    ,a.attrelid as "tableoid" 
    ,a.attnum as "columnoid" 
from 
    pg_catalog.pg_attribute a 
    inner join pg_catalog.pg_class c on a.attrelid = c.oid 
where 
     c.relname = 'mytable' -- better to use a placeholder 
    and a.attnum > 0 
    and a.attisdropped is false 
    and pg_catalog.pg_table_is_visible(c.oid) 
order by a.attnum 

Sau đó bạn có thể sử dụng tableoid, tuple columnoid để trích xuất các bình luận của mỗi cột (xem câu hỏi của tôi) .

4

này làm việc cho tôi bằng cách sử dụng PostBooks 3.2.2 DB:

select cols.column_name, 
(select pg_catalog.obj_description(oid) from pg_catalog.pg_class c where c.relname=cols.table_name) as table_comment 
,(select pg_catalog.col_description(oid,cols.ordinal_position::int) from pg_catalog.pg_class c where c.relname=cols.table_name) as column_comment 
from information_schema.columns cols 
where cols.table_catalog='postbooks' and cols.table_name='apapply' 

Kính trọng, Sylnsr

+0

Nó hoạt động, nhưng một lưu ý nhỏ từ tài liệu Postgres: Một tham số dạng obj_description chỉ yêu cầu đối tượng OID. Nó hiện không được chấp nhận vì không có sự đảm bảo rằng OID là duy nhất trên các danh mục hệ thống khác nhau; do đó, bình luận sai có thể được trả lại. –

0

Câu trả lời này là muộn một chút, nhưng nó hiện lên trên một tìm kiếm google tôi đã nghiên cứu vấn đề này. Chúng tôi chỉ cần mô tả Bảng, nhưng phương pháp sẽ giống nhau cho các cột. Các mô tả cột cũng nằm trong bảng pg_description, được tham chiếu bởi objoid.

Thêm quan điểm này:


CREATE OR REPLACE VIEW our_tables AS 
SELECT c.oid, n.nspname AS schemaname, c.relname AS tablename, d.description, 
    pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS "tablespace", 
    c.relhasindex AS hasindexes, c.relhasrules AS hasrules, c.reltriggers > 0 AS hastriggers 
    FROM pg_class c 
    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace 
    LEFT JOIN pg_tablespace t ON t.oid = c.reltablespace 
    LEFT JOIN pg_description d ON c.oid = d.objoid 
    WHERE c.relkind = 'r'::"char"; 

ALTER TABLE our_tables OWNER TO postgres; 
GRANT SELECT, UPDATE, INSERT, DELETE, REFERENCES, TRIGGER ON TABLE our_tables TO postgres; 
GRANT SELECT ON TABLE our_tables TO public; 

Sau đó chạy:

SELECT tablename, description FROM our_tables WHERE schemaname = 'public'

Quan điểm là một phiên bản sửa đổi của pg_tables xem mà thêm trong cột mô tả. Bạn cũng có thể quay xung quanh với định nghĩa khung nhìn để làm cho nó trở thành một truy vấn đơn.

25
SELECT c.table_schema,c.table_name,c.column_name,pgd.description 
FROM pg_catalog.pg_statio_all_tables as st 
    inner join pg_catalog.pg_description pgd on (pgd.objoid=st.relid) 
    inner join information_schema.columns c on (pgd.objsubid=c.ordinal_position 
    and c.table_schema=st.schemaname and c.table_name=st.relname); 
+1

tôi không hoàn toàn hiểu cách mã này hoạt động, nhưng là những gì tôi cần, vì vậy tôi không phải. – ssc

2

sửa cho @Nick và @mat gợi ý: sử dụng
SELECT obj_description('schemaName.tableName'::regclass, 'pg_class'); khi bạn có tên chuỗi (không oid).

Để tránh phải nhớ tham số 'pg_class', và để tránh concatenations xấu xí tại các cuộc gọi chức năng, như (tname||'.'||schema)::regclass, một tình trạng quá tải hữu ích cho obj_description:

CREATE FUNCTION obj_description(
     p_rname text, p_schema text DEFAULT NULL, 
     p_catalname text DEFAULT 'pg_class' 
) RETURNS text AS $f$ 
    SELECT obj_description((CASE 
     WHEN strpos($1, '.')>0 OR $2 IS NULL OR $2='' THEN $1 
     ELSE $2||'.'||$1 
    END)::regclass, $3); 
    $f$ LANGUAGE SQL IMMUTABLE; 
-- USAGE: obj_description('mytable') 
--  SELECT obj_description('s.t'); 
-- PS: obj_description('s.t', 'otherschema') is a syntax error, 
--  but not generates exception: returns the same as ('s.t') 

Bây giờ là dễ dàng để sử dụng, bởi vì tên bảng (tham số rname) là một varchar và có thể được biểu thị bằng trường được phân cách cho tên lược đồ , như trong bảng chính và truy vấn.

Xem thêm "Getting list of table comments in PostgreSQL" hoặc new pg9.3 Guide

8

Hãy chăm sóc với schemas, mã này xem xét họ:

SELECT 
    cols.column_name, 
    (
     SELECT 
      pg_catalog.col_description(c.oid, cols.ordinal_position::int) 
     FROM 
      pg_catalog.pg_class c 
     WHERE 
      c.oid = (SELECT ('"' || cols.table_name || '"')::regclass::oid) 
      AND c.relname = cols.table_name 
    ) AS column_comment 
FROM 
    information_schema.columns cols 
WHERE 
    cols.table_catalog = 'your_database' 
    AND cols.table_name = 'your_table' 
    AND cols.table_schema = 'your_schema'; 

Tài liệu tham khảo:

+1

Dòng sau cho phép linh hoạt hơn trên các tên bảng: '' 'c.oid = (SELECT ('"' || cols.table_name || '"') :: regclass :: oid) AND''' – jcristovao

+0

@jcristovao , Bạn có thể giải thích nó tốt hơn không? –

+0

Tôi sử dụng dòng đó để tôi có thể chỉ định tên_bảng chỉ một lần trong mệnh đề '' 'WHERE'''. Tuy nhiên, giải pháp đơn giản của '' 'cols.table_name''' không thành công với các tên bảng như' '' WeirdCaps''' – jcristovao

2

Chỉ cần ở đây nếu có ai đó cần đến.

Có nhiều câu trả lời ở đây, nhưng không có câu trả lời nào đơn giản như tôi muốn. Vì vậy, dựa trên câu trả lời trước đó và postgres hiện tại 9.4, tôi đã tạo truy vấn này:

SELECT 
    obj_description(format('%s.%s',isc.table_schema,isc.table_name)::regclass::oid, 'pg_class') as table_description, 
    pg_catalog.col_description(format('%s.%s',isc.table_schema,isc.table_name)::regclass::oid,isc.ordinal_position) as column_description 
FROM 
    information_schema.columns isc 

Nó tìm nạp mô tả bảng và cột, không có bất kỳ mối liên hệ khó hiểu và chuỗi ký tự xấu nào.

0

Tôi chỉ tìm thấy điều này ở đây. Nó sẽ cung cấp cho bạn với tất cả các loại siêu dữ liệu trên một bảng cụ thể (loại, giá trị mặc định, không null cờ, chiều dài, bình luận, tên khóa nước ngoài, tên khóa chính). Có vẻ như để làm việc tốt.

SELECT pg_tables.tablename, pg_attribute.attname AS field, 
    format_type(pg_attribute.atttypid, NULL) AS "type", 
    pg_attribute.atttypmod AS len, 
    (SELECT col_description(pg_attribute.attrelid, 
      pg_attribute.attnum)) AS comment, 
    CASE pg_attribute.attnotnull 
     WHEN false THEN 1 ELSE 0 
    END AS "notnull", 
    pg_constraint.conname AS "key", pc2.conname AS ckey, 
    (SELECT pg_attrdef.adsrc FROM pg_attrdef 
     WHERE pg_attrdef.adrelid = pg_class.oid 
     AND pg_attrdef.adnum = pg_attribute.attnum) AS def 
FROM pg_tables, pg_class 
JOIN pg_attribute ON pg_class.oid = pg_attribute.attrelid 
    AND pg_attribute.attnum > 0 
LEFT JOIN pg_constraint ON pg_constraint.contype = 'p'::"char" 
    AND pg_constraint.conrelid = pg_class.oid AND 
    (pg_attribute.attnum = ANY (pg_constraint.conkey)) 
LEFT JOIN pg_constraint AS pc2 ON pc2.contype = 'f'::"char" 
    AND pc2.conrelid = pg_class.oid 
    AND (pg_attribute.attnum = ANY (pc2.conkey)) 
WHERE pg_class.relname = pg_tables.tablename 
-- AND pg_tables.tableowner = "current_user"() 
    AND pg_attribute.atttypid <> 0::oid 
    AND tablename='your_table' 
ORDER BY field ASC 

Nguồn: http://golden13.blogspot.de/2012/08/how-to-get-some-information-about_7.html

0

tôi truy cập bảng ý kiến ​​như thế này:

select c.relname table_name, pg_catalog.obj_description(c.oid) as comment from pg_catalog.pg_class c where c.relname = 'table_name'; 

và cột comments thusly:

SELECT c.column_name, pgd.description FROM pg_catalog.pg_statio_all_tables as st inner join pg_catalog.pg_description pgd on (pgd.objoid=st.relid) inner join information_schema.columns c on (pgd.objsubid=c.ordinal_position and c.table_schema=st.schemaname and c.table_name=st.relname and c.table_name = 'table_name' and c.table_schema = 'public'); 
Các vấn đề liên quan