在Python上加载/使用SQL函数(避免往返)

时间:2015-08-18 21:00:56

标签: python database postgresql psycopg2

我正在编写的Python代码与PostgreSQL数据库建立psycopg2连接。我需要从这个数据库中的数据构建一些报告,所以我有一些Python procs定期运行并从一些表和好查询创建一个csv文件。

我在这里遇到的问题是我需要在我的csv报告中包含一个列,这是存储在PostgreSQL数据库中的函数的结果。该数据库由另一组人管理,因此我无法写入。我可以很容易地看到该函数的内容并模拟Python上的行为并具有我需要计算的列值,但在这种情况下,此函数会定期更改,并且不断更新Python函数是没有意义的。

所以我的问题是,每当我的代码连接到数据库时,是否有可能以某种方式将数据库函数加载到Python代码中。我可以在数据库本身上实际使用该函数,但是想象一下从Python代码对数据库函数进行900K调用来计算一个值,而不是缩放。

编辑:添加sql函数

CREATE OR REPLACE FUNCTION public.p_start(integer, integer)
 RETURNS numeric
 LANGUAGE sql
 IMMUTABLE
AS $function$
SELECT CASE WHEN $1 = 0 AND $2 = 0 THEN 0.2760
            WHEN $1 = 0 AND $2 = 1 THEN 0.0684
            WHEN $1 = 0 AND $2 = 2 THEN 0.0277
            WHEN $1 = 0 AND $2 = 3 THEN 0.0189
            WHEN $1 = 0 AND $2 = 4 THEN 0.0038
            WHEN $1 = 0 AND $2 = 5 THEN 0.0098
            WHEN $1 = 1 AND $2 = 1 THEN 0.5501
            WHEN $1 = 1 AND $2 = 2 THEN 0.2264
            WHEN $1 = 1 AND $2 = 3 THEN 0.1203
            WHEN $1 = 1 AND $2 = 4 THEN 0.0804
            WHEN $1 = 1 AND $2 = 5 THEN 0.0839
            ELSE 0.1 END;
$function$

由于

1 个答案:

答案 0 :(得分:1)

它是一个简单的SQL语言函数。

除非你可以依赖它的结构保持足够稳定,你可以为函数体写一个简单的解析器,从prosrc的{​​{1}}列中获取它的来源,我认为你是运气不好我不想这样做,因为它非常脆弱。

您应该要求数据库团队将此映射存储在一个小表而不是一个函数中,然后您只需查询表内容并缓存它们即可。它们仍然可以具有从表中返回选择结果的函数,并且在大多数情况下它将被有效地内联,并且它不会影响与使用该函数的现有应用程序的兼容性。例如。如果信息在表pg_proc中,则函数将是:

probabilities

如果失败,如果事先知道可能的输入值范围,您可以生成完整功能域的地图并将其缓存在您的应用中,例如:

CREATE OR REPLACE FUNCTION public.p_start(integer, integer)
 RETURNS numeric
 LANGUAGE sql
 IMMUTABLE
AS $function$
SELECT coalesce(
  SELECT probability FROM probabilities WHERE a = $1 and b = $2
0.1)
$function$

这很容易变成Python字典以便在本地查找。

这只适用于函数域是有限且已知的。

顺便说一句,将它定义为test=> SELECT startval, endval, p FROM generate_series(0,1) startval cross join generate_series(0,5) endval cross join p_start(startval, endval) p; startval | endval | p ----------+--------+-------- 0 | 0 | 0.2760 1 | 0 | 0.1 0 | 1 | 0.0684 1 | 1 | 0.5501 0 | 2 | 0.0277 1 | 2 | 0.2264 0 | 3 | 0.0189 1 | 3 | 0.1203 0 | 4 | 0.0038 1 | 4 | 0.0804 0 | 5 | 0.0098 1 | 5 | 0.0839 (12 rows) 然后重新定义它是错误的,除非他们IMMUTABLE并重新DROP它以确保没有任何依赖于旧定义。应该声明CREATE。如果在任何表达式索引中使用该函数,则以可产生不同值的方式重新定义STABLE函数导致不正确的查询结果。