如何确定PostgreSQL数据库对象的类型(表、视图、函数、过程或包)

am46iovg  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(118)

我正在处理一个PostgreSQL数据库,需要检查给定对象的类型,无论它是表、视图、函数、过程,还是包。目前,我使用多个查询和条件来确定对象类型,但我想知道是否有更直接的方法可以通过单个查询或更有效的方法来实现这一点。
下面是我当前代码的一部分:

cursor.execute("""
    SELECT relname, CASE relkind 
    WHEN 'r' THEN 'Table'
    WHEN 'v' THEN 'View'
    WHEN 'f' THEN 'Foreign Table'
    WHEN 'm' THEN 'Materialized View'
    WHEN 'p' THEN 'Partitioned Table'
    ELSE 'Unknown'
    END AS object_type
    FROM pg_class c
    JOIN pg_namespace n ON n.oid = c.relnamespace
    WHERE n.nspname = %s AND c.relname = %s;
""", (schema_name, object_name))

object_type = cursor.fetchone()
if object_type is None:
    object_type = 'Unknown'
else:
    object_type = object_type[1]

if object_type == 'Unknown':
    sql = f"SELECT routine_name " \
        f"FROM information_schema.routines " \
        f"WHERE specific_schema = %s AND routine_name = %s"
    cursor.execute(sql, (schema_name, object_name))
    routine_exists = cursor.fetchone()
    if routine_exists:
        object_type = 'PROCEDURE/FUNCTION'

字符串
我的问题是双重的:
有没有更直接的方法来确定PostgreSQL数据库对象的对象类型,或者使用更有效的单个查询,可能是通过连接表,而不是我目前的方法?
如何在PostgreSQL中识别数据库对象是否是包?
我尝试了以下方法:
当前方法:我使用了多个查询和条件来识别对象类型:我检查了pg_class和pg_namespace表来确定它是表还是视图。如果对象类型是“未知”,我就查询information_schema.routines表来确定它是函数还是过程。
如果可能的话,我正在寻求关于简化识别对象类型的过程的建议,以及关于识别包的任何见解。

gajydyqb

gajydyqb1#

除了查询所有可能的目录表以找到该名称的对象之外,别无他法。这可能比使用单个数据库查询的代码更有效:

SELECT relname AS object_name,
       CASE relkind
          WHEN 'r' THEN 'table'
          WHEN 'i' THEN 'index'
          WHEN 'S' THEN 'sequence'
          WHEN 't' THEN 'toast table'
          WHEN 'v' THEN 'view'
          WHEN 'm' THEN 'materialized view'
          WHEN 'f' THEN 'foreign table'
          WHEN 'p* THEN 'partitioned table'
          WHEN 'I' THEN 'partitioned index'
       END AS object_type
FROM pg_class
WHERE relname = %s
  AND relkind <> 'c'  -- will also be in pg_type
UNION ALL
SELECT proname,
       CASE prokind
          WHEN 'f' THEN 'function'
          WHEN 'p' THEN 'procedure'
          WHEN 'a' THEN 'aggregate function'
          WHEN 'w' THEN 'window function'
FROM pg_proc
WHERE proname = %s
UNION ALL
SELECT typname,
       CASE typtype
          WHEN 'b' THEN 'base type'
          WHEN 'c' THEN 'composite type'
          WHEN 'd' THEN 'domain'
          WHEN 'e' THEN 'enumeration type'
          WHEN 'p' THEN 'pseudo-type'
          WHEN 'r' THEN 'range type'
          WHEN 'm' THEN 'multirange type'
       END
FROM pg_type
WHERE typname = %s
UNION ALL
SELECT lanname, 'procedural language'
FROM pg_language
WHERE lanname = %s
UNION ALL
/* and do on for many other catalogs */

字符串
您必须为每个可能的对象类型添加一个分支。
请注意,您可能应该将模式添加到查询中,因为大多数对象都存在于模式中,并且如果两个相同类型的对象位于不同的模式中,则它们可以具有相同的名称。
另外请注意,名称仅在每个模式和对象类型中是唯一的。例如,在同一模式中可能有同名的表和函数。此外,函数重载,因此您可以在同一模式中拥有同名的不同函数。
最后,请注意,对于每个表,视图等,总是存在一个具有相同名称的复合类型。

相关问题