【问题标题】:Python script getting KilledPython脚本被杀死
【发布时间】:2018-03-29 15:15:10
【问题描述】:

环境 烧瓶 0.10.1 SqlAlchemy 1.0.10 Python 3.4.3

使用单元测试

我创建了两个单独的测试,其目标是通过 700k 记录查看数据库并进行一些字符串查找。当一次执行一个测试时,它可以正常工作,但是当整个脚本执行时:

python name_of_script.py

它在随机位置以“KILLED”退出。

两个测试的主要代码如下:

def test_redundant_categories_exist(self):
    self.assertTrue(self.get_redundant_categories() > 0, 'There are 0 redundant categories to remove. Cannot test removing them if there are none to remove.')

def get_redundant_categories(self):
        total = 0
        with get_db_session_scope(db.session) as db_session:
            records = db_session.query(Category)
            for row in records:
                if len(row.c) > 1:
                    c = row.c
                    #TODO: threads, each thread handles a bulk of rows
                    redundant_categories = [cat_x.id
                                            for cat_x in c
                                            for cat_y in c
                                            if cat_x != cat_y and re.search(r'(^|/)' + cat_x.path + r'($|/)', cat_y.path)
                                            ]
                    total += len(redundant_categories)
            records = None
            db_session.close()
        return total

另一个测试调用位于manager.py 文件中的函数,该函数执行类似的操作,但在数据库中添加了批量删除。

    def test_remove_redundant_mappings(self):
        import os
        os.system( "python ../../manager.py remove_redundant_mappings" )
        self.assertEqual(self.get_redundant_categories(), 0, "There are redundant categories left after running manager.py remove_redundant_mappings()")

是否可以在测试之间将数据保存在内存中?我不太明白单独执行测试是如何工作的,但是当背靠背运行时,该过程以 Killed 结束。

有什么想法吗?

编辑(我尝试过的事情无济于事):

  • manager.py 导入函数并在没有os.system(..) 的情况下调用它
  • import gc 并在 get_redundant_categories() 和调用 remove_redundant_mappings() 之后运行 gc.collect()

【问题讨论】:

  • 使用os.system真的有必要吗?它产生了一个新进程,可能会引起麻烦。通过 python 导入remove_redundant_mappings 似乎是一个更好的开始。
  • 我确实尝试通过 from manager import remove_redundant_mappings 导入它,但在执行过程中它说找不到模块管理器
  • 您应该检查系统的日志文件(如果您使用的是 linux,则可以使用 dmesg)。听起来该进程正在被内核杀死以保护系统。如果您将大量信息加载到内存中,则可能会在系统日志中引发 OOM(内存不足)错误。
  • 您可能希望将 os.path.join(dirname(__FILE__), '..', '..') 添加到您的 'sys.path` 以便能够导入。这不是最漂亮的线路,但仍然比你的os.system 好。也许看看ps aux | grep pythontop(或htop)的内存可以帮助调试。

标签: python python-3.x flask flask-sqlalchemy python-unittest


【解决方案1】:

在搜索高低时,我偶然在StackOverflow question/answer中看到了以下评论

我认为正在发生的事情是人们正在实例化会话而不是关闭它们。然后在不关闭会话的情况下对对象进行垃圾收集。为什么当会话对象超出范围时 sqlalchemy 会话不会自行关闭,并且总是超出我的范围。 @melchoir55

所以我在正在测试的方法中添加了以下内容:

db_session.close()

现在单元测试执行而不会被杀死。

【讨论】:

    猜你喜欢
    • 2021-05-02
    • 1970-01-01
    • 2014-11-06
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    相关资源
    最近更新 更多