Python sqlalchemy (postgresql) не возвращает реальное состояние таблицы - PullRequest
1 голос
/ 01 мая 2020

Это следующая глава моей проблемы, когда Запустите python скрипт из PostgreSQL function .

Я буду признателен за любую дополнительную помощь или идею.

I создали эту функцию на 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 триггер / функцию. Я получаю данные с шагом позади моего текущего действия.

Если я сделаю вставку сейчас, мой скрипт ничего не вернет (предположим, что моя таблица была пустой). Если я выполню другое действие, например вставка, удаление, обновление, мой сценарий будет регистрировать данные из моей первой вставки, не отражая мое текущее содержимое таблицы, и т. Д.

Пример

Состояние базы данных real table state

Что я получу со своим сценарием после срабатывания триггера what I get

Если я запустлю это 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

1 Ответ

0 голосов
/ 02 мая 2020

Решил эту ситуацию. Я уверен, что существует лучший способ решить ее, но на данный момент это все, что мне нужно.

Шаг 1 - Создать функцию

CREATE FUNCTION callMyApp()
RETURNS trigger
AS $$
import sys
sys.path.insert(0, '/path/to/my/module')
import my_module
myresult = plpy.execute('some_query_here',100)
list2=""
for i in range(len(myresult)):
    list2 = list2+ myresult[i]["some_table_row_here_returned_from_querry"]+","
list3=""
for j in range(len(myresult)):
    list3 = list3+ myresult[j]["another_table_row_here_returned_from_querry"]+","

return get_configV2.get_data(list2,list3)
$$ LANGUAGE plpythonu;

Шаг 2 - Создать триггер

CREATE TRIGGER executePython
AFTER INSERT OR UPDATE OR DELETE ON mysensor
EXECUTE PROCEDURE callMyApp();

Шаг 3 - python script

def get_data(received1,received2):
    config_file = "/some/path/here/file.txt"
def convert(string):
    mylist = list(string.split(","))
    return mylist
f = open(config_file,"w")

#write section name in config file
f.write("Ziua buna din Braila!\n")

kkk = convert(received1)
ppp = convert(received2)
for i in range(len(kkk)):
    if (kkk[i] != ""):
        output = kkk[i]+"="+ppp[i]+"\n"
        f.write(output)
f.close()

Надеюсь быть полезным и сэкономить ваше время. Спасибо за вашу поддержку Илья Эвериля

...