1

我有一个 Postgres 数据库,其中包含一个带有物化视图的表,每次通过以下用户定义的函数和触发器对表进行更改时都会自动更新:

create function refresh_matview_dohscrapemat()
returns trigger language plpgsql
as $$
begin
    refresh materialized view dohscrape;
    return null;
end $$;
create trigger refresh_matview_dohscrapemat
after insert or update or delete or truncate
on dohscrape for each statement
execute procedure refresh_matview_dohscrapemat();

我有一个 python 脚本,它使用 pandas 自动将 .csv 文件导入到这个表中,只有在我 DROP TRIGGER 用于在运行之前更新物化视图时才有效。

如果我尝试在不删除触发器的情况下运行脚本,则会收到以下错误:

sqlalchemy.exc.NotSupportedError: (psycopg2.NotSupportedError) "dohscrape" 不是物化视图 CONTEXT: SQL 语句 "refresh materialized view dohscrape" PL/pgSQL function refresh_matview_dohscrapemat() line 3 at SQL statement [SQL: 'INSERT INTO dohscrape (filename , content) VALUES (%(filename)s, %(content)s)'] [parameters: ({'filename':...(此错误的背景:http ://sqlalche.me/e/tw8g )

它说“dohscrape”不是物化视图,这是正确的,因为这是表的名称而不是物化视图。物化视图被命名为“dohscrapemat”。

错误消息中的链接指向以下信息:

NotSupportedError 如果使用了数据库不支持的方法或数据库 API,则会引发异常,例如在不支持事务或关闭事务的连接上请求 .rollback()。

此错误是 DBAPI 错误,源自数据库驱动程序 (DBAPI),而不是 SQLAlchemy 本身。

但我不明白这与更新物化视图的触发器引起/相关的错误有什么关系,我认为这是根本问题,因为删除它可以解决错误。

一旦我让脚本上传到表并重新创建触发器,一切正常,但我希望能够运行此脚本而不必删除并重新创建触发器。

为什么刷新物化视图的触发器会导致导入错误?为什么 pandas/sqlalchemy/psycopg2 会将我的表与其物化视图混淆?

上传到数据库的python脚本中的代码片段是:

for files in source:
    if files.endswith(".csv"):
        df = pd.read_csv(os.path.join(sourcepath,files))
        df.to_sql(name='dohscrape',con=dbconn,if_exists='append',index=False)

我正在使用 Python 3.7 和 Postgres 11。

4

1 回答 1

0

它说“dohscrape”不是物化视图,这是正确的,因为这是表的名称而不是物化视图。物化视图被命名为“dohscrapemat”。

所以你的触发功能显然是错误的。代替

    refresh materialized view dohscrape; -- error

    refresh materialized view dohscrapemat;
于 2019-01-31T01:29:30.157 回答