关于Snowflake中表创建者查询替代方法及创建表时强制指定用户名的技术问询
针对你关于Snowflake表创建者信息的两个问题,我来整理实用的解决方案:
INFORMATION_SCHEMA.QUERY_HISTORY,还有哪些方法获取Snowflake表的创建者信息? 这里有几个更直接或者范围更广的方法,根据你的权限和需求选择:
查询系统视图获取直接字段
Snowflake的INFORMATION_SCHEMA.TABLES(当前数据库范围)和ACCOUNT_USAGE.TABLES(全账户范围)视图里都自带CREATED_BY字段,直接就能拿到创建表的用户名,比查历史SQL高效多了。
示例查询:-- 查当前数据库指定schema下的表创建者 SELECT TABLE_NAME, CREATED_BY, CREATED FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'YOUR_SCHEMA_NAME'; -- 查全账户指定数据库的所有表创建者(需要ACCOUNTADMIN或相关权限) SELECT TABLE_NAME, CREATED_BY, CREATED, DATABASE_NAME, SCHEMA_NAME FROM ACCOUNT_USAGE.TABLES WHERE DATABASE_NAME = 'YOUR_DB_NAME';用账户级查询历史视图
你排除了INFORMATION_SCHEMA.QUERY_HISTORY(只保留7天数据),但ACCOUNT_USAGE.QUERY_HISTORY默认保留1年的历史,范围覆盖全账户。可以筛选CREATE TABLE类型的语句找到创建者:SELECT QUERY_TEXT, USER_NAME, START_TIME FROM ACCOUNT_USAGE.QUERY_HISTORY WHERE QUERY_TYPE = 'CREATE TABLE' AND QUERY_TEXT ILIKE '%YOUR_TABLE_NAME%' ORDER BY START_TIME DESC;依赖自定义标签或注释
如果团队有建表规范,要求手动添加创建者信息到表的标签或注释里,也可以通过以下方式查询:-- 查表的CREATED_BY标签值 SELECT t.TABLE_NAME, ta.TAG_VALUE AS CREATED_BY FROM INFORMATION_SCHEMA.TABLES t JOIN INFORMATION_SCHEMA.TAGS ta ON t.TABLE_CATALOG = ta.TAG_DATABASE AND t.TABLE_SCHEMA = ta.TAG_SCHEMA AND t.TABLE_NAME = ta.TAG_OBJECT_NAME WHERE ta.TAG_NAME = 'CREATED_BY'; -- 从表注释中提取创建者(假设注释格式包含“创建者:xxx”) SELECT TABLE_NAME, REGEXP_SUBSTR(COMMENT, '创建者:(\\w+)', 1, 1, 'e') AS CREATED_BY FROM INFORMATION_SCHEMA.TABLES WHERE COMMENT IS NOT NULL;
有两种可靠的方案,分别适合不同的场景:
用标签策略(Tag Policy)强制要求
这是Snowflake官方推荐的合规方案,通过标签策略强制所有新创建的表必须设置记录创建者的标签,否则建表操作会直接失败。
步骤如下:- 先创建一个用于记录创建者的标签:
CREATE TAG CREATED_BY; - 创建标签策略,规定目标schema下的表必须设置
CREATED_BY标签:CREATE TAG POLICY ENFORCE_CREATED_BY_TAG ON SCHEMA FOR TAG CREATED_BY AS $$ EXISTS (SELECT 1 FROM TABLE(GET_TAG_ON_CURRENT_OBJECT('CREATED_BY'))) $$ WITH DESCRIPTION = '强制所有表必须设置CREATED_BY标签,记录创建者'; - 将策略应用到目标schema(或数据库,范围更大):
APPLY TAG POLICY ENFORCE_CREATED_BY_TAG ON SCHEMA YOUR_DB.YOUR_SCHEMA;
用户建表时必须指定标签值,通常可以用
CURRENT_USER()自动填充:CREATE TABLE orders (id INT, amount NUMBER(10,2)) SET TAG CREATED_BY = CURRENT_USER();之后就能通过标签轻松统一获取所有表的创建者信息,完全避免遗漏。
- 先创建一个用于记录创建者的标签:
用存储过程封装建表逻辑+权限控制
如果不想用标签策略,可以把建表逻辑封装到存储过程里,自动带上创建者信息,然后限制用户只能调用存储过程,不能直接执行CREATE TABLE。
示例存储过程(简化版):CREATE OR REPLACE PROCEDURE CREATE_TABLE_WITH_CREATOR(table_name VARCHAR, column_defs VARCHAR) RETURNS VARCHAR LANGUAGE SQL AS $$ BEGIN -- 自动添加创建者标签,无需用户手动输入 EXECUTE IMMEDIATE 'CREATE TABLE ' || table_name || ' (' || column_defs || ') SET TAG CREATED_BY = ''' || CURRENT_USER() || ''''; RETURN '表 ' || table_name || ' 创建成功,创建者:' || CURRENT_USER(); END; $$;然后调整权限:
-- 给用户角色授予存储过程执行权限 GRANT EXECUTE ON PROCEDURE CREATE_TABLE_WITH_CREATOR(VARCHAR, VARCHAR) TO ROLE YOUR_USER_ROLE; -- 收回用户角色直接建表的权限 REVOKE CREATE TABLE ON SCHEMA YOUR_DB.YOUR_SCHEMA FROM ROLE YOUR_USER_ROLE;用户只能通过调用存储过程建表,创建者信息会自动写入标签,完全不需要用户手动指定,也避免了违规操作。
内容的提问来源于stack exchange,提问作者Austin Jackson

