通过Django orm加载数据非常耗费内存

时间:2014-02-13 11:04:32

标签: python django django-orm

所以我有一个脚本加载从python pickle文件创建的数据。

dump_file = open('movies.pkl')
movie_data = pickle.load(dump_file)

@transaction.commit_manually
def load_data(data):
    start = False
    counter = 0
    for item in data:
                counter += 1
            film_name = item.decode(encoding='latin1')
            print "at", film_name, str(counter), str(len(data))
            film_rating = float(data[item][0])
            get_votes = int(data[item][2]['votes'])
            full_date = data[item][2]['year']
            temp_film = Film(name=film_name,date=full_date,rating=film_rating, votes=get_votes)
            temp_film.save()
            for actor in data[item][1]:
                actor = actor.decode(encoding='latin1')
                print "adding", actor
                person = Person.objects.get(full=actor)
                temp_film.actors.add(person)
            if counter % 10000 == 0 or counter % len(data) == 0:
                    transaction.commit()
                    print "COMMITED"

load_data(movie_data)

所以这是一个非常大的数据集。它占用了大量的内存,它慢慢变成了爬行,而在过去我的解决方案就是从我离开的地方重新启动脚本,因此需要花费很多时间才能将所有内容保存到数据库中。

我想知道是否有更好的方法来做到这一点(即使我的代码中的优化会很好)除了编写原始sql来输入数据之外?我之前尝试过JSON灯具,它比这种方法更糟糕。

2 个答案:

答案 0 :(得分:1)

如果movie_data的大小很大,您可能希望先将其分成较小的文件,然后逐个迭代它们。 请记住释放以前加载的pkl文件的内存或保留覆盖相同的变量。 如果电影数据是一个列表,你可以通过切片(例如movie_data = movie_data [1000:]来迭代它们来释放1000条记录的内存,以减少一段时间内的内存消耗

答案 1 :(得分:1)

您可以在QuerySet对象上使用bulk_create()方法在单个查询中创建mutliple对象,它可以在Django 1.4中使用。请仔细阅读以下文档链接 -

您还可以通过在python中使用“with”关键字打开文件来优化代码。 “使用”语句,它会自动为您关闭文件,执行with块内的所有操作,因此它会保持文件为您打开,并在您不在with块时关闭文件。