Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Postgres:有没有一种方法可以在INSERT语句之后执行代码?_Python_Django_Postgresql_Insert - Fatal编程技术网

Python Postgres:有没有一种方法可以在INSERT语句之后执行代码?

Python Postgres:有没有一种方法可以在INSERT语句之后执行代码?,python,django,postgresql,insert,Python,Django,Postgresql,Insert,这可能看起来很奇怪,但我很好奇,是否可以在postgres数据库中的INSERT语句之后执行代码块 具体来说,我感兴趣的是在pg数据库中出现INSERT语句之后执行Python代码。解决这个问题的简单方法是使用postgresql 您可以添加插入/更新后触发器,该触发器将执行以下操作: CREATE OR REPLACE FUNCTION on_insert() RETURNS trigger AS $$ BEGIN execute E'NOTIFY ENTITY_CHANGE, \'

这可能看起来很奇怪,但我很好奇,是否可以在postgres数据库中的INSERT语句之后执行代码块


具体来说,我感兴趣的是在pg数据库中出现INSERT语句之后执行Python代码。

解决这个问题的简单方法是使用postgresql

您可以添加插入/更新后触发器,该触发器将执行以下操作:

CREATE OR REPLACE FUNCTION on_insert() RETURNS trigger AS
$$
BEGIN

    execute E'NOTIFY ENTITY_CHANGE, \'' || NEW.id || E'\'';

    RETURN NEW;
END
$$
LANGUAGE 'plpgsql' VOLATILE;

create trigger trig_on_insert
after insert on ENTITY
for each row
execute procedure on_insert_to_t();
ENTITY\u CHANGE
是您可以选择任何频道的标识符

您的应用程序应该在单独的线程(或进程)中访问它,并执行所需的操作:

from django.db import connection

curs = connection.cursor()
curs.execute("LISTEN ENTITY_CHANGED;")

while not_finish:
    if select.select([connection],[],[],5) == ([],[],[]):
        print "Timeout"
    else:
        connection.poll()
        while connection.notifies:
            notify = connection.notifies.pop()
            entity_id = notify.payload
            do_post_save(entity_id)
唯一需要注意的是,通知不是事务性的,如果发生灾难性故障,通知可能会丢失。在这种情况下,应用程序收到通知,但在完成通知处理之前崩溃(或被杀死),这样的通知将永远丢失

如果您需要保证保存后处理始终进行,则需要维护一些任务表。在insert/update触发器之后,应该向该表添加任务,一些python进程应该轮询该表并执行所需的处理。缺点是轮询——当系统不保存实体时,它会执行不必要的查询


您可以将这两种方法结合起来,以获得最佳效果,即使用notify开始处理,但处理器应该从由触发器填充的任务表中获取任务。在应用程序启动期间,如果有未完成的工作,则应运行处理程序。

是否要在@Sathish中编写插入后触发器在共享数据库A上执行
INSERT
语句后,我希望应用程序执行
save()
语句插入数据库B的命令。@muistooshort-Yes。在Django,事实上。在Django的土地上,不是有某种回调或者在save hook之后处理这个问题吗?我认为你不会在触发器中运行数据库中的一堆Django东西。@muistooshort Django中有
post\u save
信号。但问题是数据库A正被外部应用程序插入,因此
post_save
将无法工作,因为
save
操作正在其他地方进行。这看起来很有希望,但有可能从INSERT语句中提取数据吗?例如,如果出现
插入到用户(姓名、年龄)值(“Joe”,30)
,那么它将
通知
应用程序要处理的有效负载字符串中的数据?太好了!通知的有效负载是否有空间限制?如果数据包含一些文本字段(可能很重要),可以吗?AFAIR限制大约为2000字节,请参阅pg文档,它们有所有详细信息。最好先传递id,然后从表本身读取所有值,或者考虑一下我在文章中描述的tasks表,因为这样可以避免listen/notify的事务问题。