【发布时间】:2021-01-07 23:04:07
【问题描述】:
这是Run python script from PostgreSQL function时我的问题的下一章。
如果有任何进一步的帮助或想法,我将不胜感激。
我已经在 PostgreSQL 上创建了这个函数
CREATE FUNCTION getSomeData()
RETURNS trigger
AS $$
import subprocess
subprocess.call(['/path/to/your/virtual/environment/bin/python3', '/some_folder/some_sub_folder/get_data.py'])
$$
LANGUAGE plpythonu;
并触发
CREATE TRIGGER executePython
AFTER INSERT OR UPDATE OR DELETE ON mysensor
FOR EACH ROW EXECUTE PROCEDURE callMyApp();
使用 get_data.py
from sqlalchemy import create_engine
SQLALCHEMY_DATABASE_URI = 'postgresql:///database_name'
db = create_engine(SQLALCHEMY_DATABASE_URI)
some_file = "my_file.txt"
#store pair of id and value
someDictionary = {}
with db.connect() as dbcon:
#Get sensor unique ID and room name for every room_id from mysensor existent in rooms
mydata = dbcon.execute('SELECT mytable1.uid, mytable2.name FROM mytable1,mytable2 WHERE mytable1.some_id = mytable2.id')
for row in mydata:
# add key,value from touple to dictionary
someDictionary[row[0]] = row[1]
f = open(config_file,"w")
#write section name in config file
f.write("[somepairing]\n")
for key, value in someDictionary.items():
print(key, value)
f.write(key + "=" +value+"\n")
f.close()
当我通过我的 Postgresql 触发器/函数运行此脚本时,我会在当前操作后一步获取数据。
如果我现在进行插入,我的脚本将不会返回任何内容(假设我的表是空的)。 如果我进行其他操作,例如插入、删除、更新,我的脚本将记录我第一次插入的数据,而不反映我当前的表格内容,等等。
示例
如果我单独运行这个 python 脚本,而不是通过触发器,一切都很好并获得准确的表状态。
非常感谢您的帮助。
我已经根据我的代码编辑了,现在我的函数就是这种形式
CREATE FUNCTION callMyApp()
RETURNS trigger
AS $$
import sys
sys.path.insert(0, '/path/to/my/module')
import get_config
return get_config.get_data()
$$ LANGUAGE plpythonu;
新的问题是我在get_config中导入的模块无法识别/脚本不知道如何定位。
Error: ERROR: ImportError: No module named sqlalchemy
【问题讨论】:
-
脚本使用自己的会话和事务。默认事务隔离级别是 READ COMMITTED。如果您希望能够从触发器中读取当前事务,我建议将您的
get_data转换为库并在触发器中使用它,将 database access object 作为参数传递给函数。 -
@IljaEverilä 我已根据您的建议更新了我的代码。我已经将我的脚本作为模块导入到 postgresql /plpythonu 函数中。 CREATE FUNCTION callMyApp() RETURNS trigger AS $$ import sys sys.path.insert(0, '/path/to/my/module') import get_config return get_config.get_data() $$ LANGUAGE plpythonu;我面临的另一个问题是无法识别我的模块/python 脚本请求的模块。
-
这不会解决可能的其他环境/模块问题,但在这种情况下,我建议根本不使用 SQLA,而是将
plpy模块提供给您的 UDF,将其传递给库根据需要发挥作用。您必须熟悉它,但它与 Python 的其他 DB API 并没有太大区别。今天晚些时候,我将尝试提出一个正确的答案,而不是仅仅提供 cmets。
标签: python postgresql sqlalchemy flask-sqlalchemy database-trigger