Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.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 从原子数据库事务内部与外部世界通信_Python_Mysql_Django_Transactions_Atomicity - Fatal编程技术网

Python 从原子数据库事务内部与外部世界通信

Python 从原子数据库事务内部与外部世界通信,python,mysql,django,transactions,atomicity,Python,Mysql,Django,Transactions,Atomicity,我正在实现一个导入工具(Django 1.6),它接受一个可能非常大的CSV文件,对其进行验证,并根据用户确认是否导入该文件。考虑到潜在的大文件大小,文件的处理是通过flowy(Amazon的SWF上的python包装器)完成的。每个导入作业都保存在数据库的一个表中,工作流非常简单,只包含一个活动,它基本上调用一个方法来运行导入,并将有关文件处理的所有必要信息保存在数据库中作业的记录中 棘手的事情是:我们现在必须使这个导入原子化。要么保存所有记录,要么不保存任何记录。但导入表中保存的内容之一是导

我正在实现一个导入工具(Django 1.6),它接受一个可能非常大的CSV文件,对其进行验证,并根据用户确认是否导入该文件。考虑到潜在的大文件大小,文件的处理是通过flowy(Amazon的SWF上的python包装器)完成的。每个导入作业都保存在数据库的一个表中,工作流非常简单,只包含一个活动,它基本上调用一个方法来运行导入,并将有关文件处理的所有必要信息保存在数据库中作业的记录中

棘手的事情是:我们现在必须使这个导入原子化。要么保存所有记录,要么不保存任何记录。但导入表中保存的内容之一是导入的进度,该进度根据文件读取器的位置计算:

progress = (raw_data.tell() * 100.0) / filesize
客户端的AJAX progressbar小部件使用这个进度。因此,简单地将
@transaction.atomic
添加到循环文件并导入行的方法中并不是一个解决方案,因为只有在提交时才会保存进度


CSV文件仅包含一种类型的记录,并影响单个表。如果我能以某种方式只在这个表上执行一个事务,让job表自由地更新progress列,那将是理想的。但从我目前的发现来看,这似乎是不可能的。到目前为止,我能想到的唯一解决方案是在每次需要更新进度时打开一个新线程和其中的一个新数据库连接。但我一直在想…这会奏效吗?难道没有更简单的解决方案吗?

一种简单的方法是使用
读取未提交的
事务隔离级别。这可能允许脏读,这将允许您的其他进程查看进度,即使事务尚未提交。但是,这是否有效将取决于数据库。(我不熟悉MySQL,但这在PostgreSQL中不起作用,因为
readuncommitted
readcommitted
的工作方式相同)

关于您提出的解决方案,您不一定需要一个新的线程,您实际上只需要一个到数据库的新连接。在Django实现这一点的一种方法可能是利用。我在想象这样的事情:

  • 如文档中所述,使用不同的名称向
    数据库添加一个新条目
    ,但设置与
    default
    相同。从Django的角度来看,我们正在使用多个数据库,尽管我们实际上只是想获得到同一个数据库的多个连接

  • 当需要更新进度时,请执行以下操作:

    JobData.objects.using('second_db').filter(id=5).update(progress=0.5)
    
    这应该发生在它自己的自动提交事务中,允许web服务器查看进度


  • 现在,这有用吗?我真的不知道,我从来没有试过这样的东西

    嗨,Kevin,与此同时,在阅读Django中的DB管理时,我还想到了使用第二个别名来处理相同的数据。它确实有效!我只需使用参数调用事务,而不使用参数,这可能会在默认数据库中创建一个事务,然后我使用成员模型的普通接口(例如,
    Membership.objects.create(…)
    ),并在与ImportJob对象交互时使用添加
    (如您的示例所示)。进程中间的异常导致没有数据导入的回滚,进度条工作:“@艾莉尔:太好了,很高兴听到它。”