使用 python 执行 PL/PGSQL 块而不将它们存储到数据库中

Posted

技术标签:

【中文标题】使用 python 执行 PL/PGSQL 块而不将它们存储到数据库中【英文标题】:executing PL/PGSQL blocks using python without storing them into database 【发布时间】:2013-01-12 12:12:19 【问题描述】:

我正在使用 python 构建 Django 应用程序,该应用程序预计会接收大量数据,我已经研究了一些可以提高性能的 PL/PGSQL 程序。这些过程存储在文件中,我不想在数据库上创建它们。

我只想能够使用 postgresql_psycopg2 执行它们,另一个棘手的部分是我希望能够在执行之前更改文件中的一些参数,但不确定如何处理它。

这是我的 Python 代码

        pg_script = os.path.join(getattr(settings, 'BASE_DIR'),'myapp/apps/rating/sql/rating_create_article_rating.sql')

        cursor = connection.cursor()
        cursor.execute("run script %s" % pg_script)

这里是 rating_create_article_rating.sql

DECLARE
    article_rec   publication_article%ROWTYPE;
    user_rec      auth_user%ROWTYPE;
    up            integer := 1;
    down          integer := -1;
    l_counter     integer := 0; -- local counter
    cnt           integer;
    p_content_type_id integer;
BEGIN



    LOOP
        -- RANDOM ARTICLE
        SELECT *
        INTO article_rec
        FROM publication_article
        order by random()
        LIMIT  1;

        -- RANDOM USER
        SELECT *
        INTO user_rec
        FROM auth_user
        order by random()
        LIMIT  1;

        BEGIN
          INSERT INTO rating_rate (rated_by_id, rated_at, content_type_id, object_id, rate, language)
          VALUES (user_rec.id, now(), p_content_type_id, article_rec.id, 1, 'en');
          l_counter := l_counter+1;
        EXCEPTION
              WHEN unique_violation THEN

        END;



        EXIT WHEN l_counter>cnt;
    END LOOP;


    RETURN;
END;
$$ LANGUAGE plpgsql;

当我将上面的代码作为存储函数执行时,上面的代码有效,否则运行脚本不起作用,我收到以下错误

ERROR:  syntax error at or near "run" at character 1
STATEMENT:  run script /Users/mo/Projects/pythonic/myapp-env/myapp/myapp/apps/rating/sql/rating_create_article_rating.sql

我还想知道是否有办法将参数传递给文件并从 pl/pgsql 处理它?

非常感谢

【问题讨论】:

您可以使用匿名函数。 DO $$ -- Code $$; postgresql.org/docs/current/static/sql-do.html 在使用匿名函数时,是引用脚本位置还是读取脚本内容并将其转储到光标中? 不知道你为什么不把过程放在数据库中并调用它。我想应该会更快。 【参考方案1】:

首先,我更喜欢将这些东西放在函数中。一个重要的原因是,这有助于分离 sql​​ 和应用程序代码,使其更易于阅读和查找所需内容。函数还可以进行一些优化。

如果这还不够,请使用 DO 块。 DO 块有许多重要的限制。例如,它们不能返回结果。这意味着,如果您想返回有关插入或类似内容的有用信息,则不能这样做。

DO 创建一个没有返回类型的匿名函数。您可以将您的函数体包含在 DO LANGUAGE PLPGSQL $$ .. $$; 块中,它会立即运行。

【讨论】:

以上是关于使用 python 执行 PL/PGSQL 块而不将它们存储到数据库中的主要内容,如果未能解决你的问题,请参考以下文章

如何从终端执行php块而不保存到文件

执行 SELECT 语句并丢弃 PL/pgSQL 中的结果

如何在 PostgreSQL、PL/pgSQL 上执行匿名代码块切换 CASE 语句?

PL/pgSQL 函数 - 遍历特定列并在循环中执行第二个查询

如何在 C# 中从 Npgsql 4.1.5.0 执行匿名块 PL/pgSQL (PostgreSQL 13)

PL/pgSQL 重启生成序列