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

时间:2013-01-12 12:12:19

标签: python postgresql postgresql-9.2

我正在使用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处理它?

非常感谢

1 个答案:

答案 0 :(得分:1)

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

如果这还不够,请使用DO块。 DO块有许多重要的限制。例如,他们无法返回结果。这意味着如果您想要返回有关插入等的有用信息,则无法执行此操作。

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