我正在编写的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$
由于
答案 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
函数将导致不正确的查询结果。