我正在运行Postgresql 9.4,我对它如何处理plpython导入感到困惑,特别是关于Decimal。
第一个例子:
CREATE OR REPLACE FUNCTION devel.foo()
RETURNS void AS
$BODY$
def myfoo():
eval("Decimal('40.0')")
myfoo()
plpy.notice("done")
$BODY$
LANGUAGE plpythonu VOLATILE
COST 100;
ALTER FUNCTION devel.foo()
OWNER TO postgres;
SELECT devel.foo();结果:
错误: NameError:未定义名称'Decimal‘
这有点令人惊讶,因为PostgreSQL9.4中的一个变化是,它应该隐式地使用Decimal,而不是在plpython中使用float。但是,好吧,让我们添加导入:
CREATE OR REPLACE FUNCTION devel.foo()
RETURNS void AS
$BODY$
from decimal import Decimal
def myfoo():
eval("Decimal('40.0')");
myfoo()
plpy.notice("done")
$BODY$
LANGUAGE plpythonu VOLATILE
COST 100;
ALTER FUNCTION devel.foo()
OWNER TO postgres;
select devel.foo()再一次:
错误: NameError:未定义名称'Decimal‘
现在,让我们尝试将导入放在函数中:
CREATE OR REPLACE FUNCTION devel.foo()
RETURNS void AS
$BODY$
def myfoo():
from decimal import Decimal
eval("Decimal('40.0')")
myfoo()
plpy.notice("done")
$BODY$
LANGUAGE plpythonu VOLATILE
COST 100;
ALTER FUNCTION devel.foo()
OWNER TO postgres;
select devel.foo();结果:devel.foo()现在执行时没有问题,打印“完成”。另一件奇怪的事情是:以下几点也起作用:
CREATE OR REPLACE FUNCTION devel.foo()
RETURNS void AS
$BODY$
from decimal import Decimal
def myfoo():
var = Decimal('40.0')
eval("Decimal('40.0')")
myfoo()
plpy.notice("done")
$BODY$
LANGUAGE plpythonu VOLATILE
COST 100;
ALTER FUNCTION devel.foo()
OWNER TO postgres;问题:为什么在myfoo()中看不到顶级导入?如果我在函数中使用十进制,为什么它突然起作用了?
发布于 2021-01-20 15:26:35
这是这里文档中的python行为。plpythonu执行环境不是全局的。
注意,eval()不能访问封闭环境中的嵌套作用域(非局部变量)。
在python (PostgreSQL之外)中尝试以下代码:
def bar():
from decimal import Decimal
def foo():
return eval("Decimal('40.0')")
return foo()
print(bar())它在NameError: name 'Decimal' is not defined中失败了。
使用Decimal将global放入您的全局中是有效的:
def bar():
from decimal import Decimal
global Decimal
def foo():
return eval("Decimal('40.0')")
return foo()
print(bar())https://stackoverflow.com/questions/65809966
复制相似问题