2013-01-12 30 views
0

我正在使用python構建Django應用程序,應用程序預計會接收大量的數據,我曾參與一些可以提高性能的PL/PGSQL過程。這些過程存儲在文件中,我不想在數據庫上創建它們。使用python執行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處理它的方法?

非常感謝

+3

您可以使用匿名函數。 'DO $$ - Code $$;' – Keyo

+0

http://www.postgresql.org/docs/current/static/sql-do.html –

+0

使用匿名函數時,是否引用腳本位置或者是否讀取腳本內容並將其轉儲到光標中? –

回答

1

首先,我更喜歡把這些東西放在函數中。其中一個重要原因是,這有助於將sql和應用程序代碼分開,使其更易於閱讀和查找所需內容。功能也可能會發生一些優化。

如果這還不夠,請使用DO塊。 DO塊有一些重要的限制。例如,他們無法返回結果。這意味着如果你想返回有關插入或類似的有用信息,你不能這樣做。

DO創建一個沒有返回類型的匿名函數。您可以在DO LANGUAGE PLPGSQL $$ .. $$;區塊中包含您的功能主體,並立即運行。

相關問題