[英]Flask, SQLAlchemy and high memory usage when streaming response
我正在寫一個頁面,從我的數據庫下載數百萬條記錄。 我計划在一個內存有限的環境中運行它。 因此,我想要流式傳輸CSV數據。 此代碼由於某種原因仍然使用大量內存,並且在完成下載后內存不會被釋放。 造成這種泄漏的原因。 我的應用程序從占用30mb的內存到2GB
@app.route('/admin/querydb', methods=['GET', 'POST'])
@admin_filter
def admin_query_db():
if request.method == 'POST':
query = model.DriverStop.query.join(model.DriverDailyRoute, model.Agency).join(model.User)
if 'date_filter_start' in request.form:
start = datetime.datetime.strptime(request.form['start_date'], '%Y-%m-%d')
start -= datetime.timedelta(days=1)
query = query.filter(model.DriverDailyRoute.date >= start)
if 'date_filter_end' in request.form:
end = datetime.datetime.strptime(request.form['end_date'], '%Y-%m-%d')
query = query.filter(model.DriverDailyRoute.date < end)
if not 'recipient' in request.form:
query = query.filter(model.Agency.agency_type != model.Agency.RECIPIENT)
if not 'donor' in request.form:
query = query.filter(model.Agency.agency_type != model.Agency.DONOR)
header = ['Username', 'Last Name', 'First Name', 'Agency Name',
'Agency Type', 'City', 'Date', 'Time', 'Is Special Stop', 'Cargo Temperature',
'Prepared', 'Produce', 'Dairy', 'Raw Meat', 'Perishable', 'Dry Goods',
'Bread', 'Total']
def csv_line(items):
return ''.join(['"' + str(s).replace('"', '""') + '",' for s in items][:-1])
def gen_csv():
yield csv_line(header) + '\n'
for q in query.all():
yield csv_line([q.route.driver.username, q.route.driver.last_name, q.route.driver.first_name,
q.agency.name, q.agency.agency_type, q.agency.city, q.route.date,
q.time, q.special_stop, q.cargo_temp, q.prepared, q.produce,
q.dairy, q.raw_meat, q.perishable, q.dry_goods, q.bread, q.total_up()]) + '\n'
return Response(gen_csv(), mimetype='text/csv')
drivers = model.User.query.filter_by(acct_type=model.User.DRIVER).order_by(model.User.active, model.User.last_name, model.User.first_name, model.User.username).all()
agencies = model.Agency.query.order_by(model.Agency.active, model.Agency.name).all()
return render_template('admin/dbquery.html', page_title='Database Query', drivers=drivers, agencies=agencies)
我的一些其他頁面也有這種行為,它們在大型查詢后不釋放內存。
調用Query.all()
會導致SQLAlchemy從數據庫查詢中加載所有結果並將它們轉換為內存中的列表。 您應該使用Query.yield_per()
批量加載數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.