如何将“ALTER table [...] ADD column”之类的更改记录到我的 PostgreSQL 表中?

Posted

技术标签:

【中文标题】如何将“ALTER table [...] ADD column”之类的更改记录到我的 PostgreSQL 表中?【英文标题】:How can I log changes like "ALTER table [...] ADD column" to my PostgreSQL table? 【发布时间】:2020-01-06 02:06:28 【问题描述】:

我想记录一列何时添加到我的表中。我已经找到了概述 (information_schema.columns)。但是,这里缺少时间,甚至不显示已删除的列。我正在使用 PostgreSQL 8.4.4,我可以更新到 9.6.5

我的想法是在information_schema.columns 上触发,但这不起作用,因为它不是表格。

【问题讨论】:

为什么要在 2019 年升级到“仅”9.6?为什么不升级到当前版本? (11 - 即将成为 12)如果由于某种原因你真的被限制在 9.6,你至少需要 9.6.15,这是 9.6 分支中的最新版本 【参考方案1】:

对于较新版本的 postgres,您可以使用 event triggers。除非您用 C 编写函数来解析 pg_ddl_command 类型,否则您似乎无法获取有关添加的实际列的信息,但您可以获得有关受影响的表、谁做的以及何时做的信息:

CREATE TABLE alter_table_log (
  id bigserial primary key,
  tstamp timestamp with time zone default now(),
  table_id regclass,
  altered_by regrole
);

GRANT insert, select on table alter_table_log to public;
GRANT usage on alter_table_log_id_seq to public;


CREATE OR REPLACE FUNCTION log_alter_trig() 
RETURNS event_trigger 
LANGUAGE plpgsql AS
$$
  BEGIN
        INSERT INTO alter_table_log(table_id, altered_by)
        select obj.objid::regclass, current_user::regrole
        FROM (select * from pg_event_trigger_ddl_commands()) as obj;
  END
$$;

CREATE EVENT TRIGGER log_alter_trig
  ON ddl_command_end
  WHEN TAG IN ('ALTER TABLE')
  EXECUTE PROCEDURE log_alter_trig();

create table test (a text);
alter table test add column b text;
select * from alter_table_log;

 id |            tstamp             | table_id | altered_by
----+-------------------------------+----------+------------
  1 | 2019-09-03 13:21:36.361964+00 | test     | postgres

您将无法在 8.4 中执行此操作。我建议更新到 11。在不再支持之前,9.6 不会为您争取太多时间。

【讨论】:

【参考方案2】:

您应该能够利用Postgres Reporting and Logging tools:

基本上,您需要将log_statement 参数设置为(至少)'ddl'

ddl记录所有数据定义语句,如CREATEALTERDROP语句

那么您应该能够在服务器日志中使用 grep 表达式,例如 "alter table <mytable> add column"

PS:

您需要reload the configuration 才能使更改生效

如果大量 DDL 操作发生在您的数据库中,此设置可能会生成大量日志,从而使此解决方案有点过头了

【讨论】:

首先,谢谢。有用。但这并不是我真正想要的。登录已经在 (log_destination = 'stderr') 上运行,我不能将其设置为 ('csvlog') 以获得更好的概览,因为我正在使用外部软件。现在我必须定期解析日志文件并将其写入数据库。是否有更优雅的解决方案可以直接格式化保存数据?我可以设置(log_destination to 'stderr' and 'csvlog')并只保存(log_statement = 'ddl' in 'csvlog')吗? @Andreas;好吧,您可以使用如下表达式设置多个日志记录目标:log_destination('stderr,csvlog')。但是,我认为每个目的地不可能有不同的登录设置。

以上是关于如何将“ALTER table [...] ADD column”之类的更改记录到我的 PostgreSQL 表中?的主要内容,如果未能解决你的问题,请参考以下文章

sql [ALTER TABLE ADD COLUMN]将新列添加到现有表#SQL

SQL ALTER TABLE ADD PRIMARY KEY 错误 1064

create index 与 alter table add index 区别

如何将thinkcmf导入eclipse

如何将CString转换成wstring

如何将Ios文件上传到