Мне нужен индикатор выполнения для обработки данных в Flask проекте . В дополнение к примерам кода я не могу просто сосчитать в al oop, но должен отобразить ход обработки, выполняемой по отдельному маршруту , то есть процент уже обработанных изображений для загрузка и обработка нескольких изображений. Я использую подход, при котором процесс обработки записывает количество изображений для обработки в качестве атрибута пользователя в базу данных (current_user.multipleupload = len (pics)) * , и штрих-код прогресса проверяет изначально сколько уже обработанных картинок существует для текущего пользователя новые записи для этого пользователя были созданы с начала индикатора выполнения (itemcount-iteminital)
В прототипе подход работает. Но я вижу следующие проблемы:
Это приводит к большому количеству обращений к базе данных, проверяя по истечении time.sleep (2) непрерывно количество обработанных изображений для текущего пользователь.
Мне пришлось использовать начальный time.sleep (0,5) при инициализации прогресса l oop, потому что в противном случае процесс отображения прогресса уже начался до того, как обработка изображения запустил и положил количество снимков, которые нужно обработать, в базу данных. Значение 0.5 было найдено, играя, и я не ожидаю, что это будет работать в производственном процессе с другой инфраструктурой и одновременным доступом.
Какой лучший способ получить информацию от обработка l oop до индикатора выполнения l oop? Я пытался использовать сеанс вместо базы данных, что это не сработало вообще.
Progress l oop:
@items.route('/progress')
def progress():
@stream_with_context
def import_progress():
time.sleep(0.5)
with current_app.app_context():
iteminital = Item.query.filter_by(owner=current_user).count() - 1
if current_user.multipleupload:
itemstargetcount = current_user.multipleupload
continueloop = True
while continueloop:
with current_app.app_context():
itemcount = Item.query.filter_by(owner=current_user).count()
percentage = round(100 * (itemcount-iteminital) / itemstargetcount)
sse_id = str(percentage)
sse_data = str(percentage)
sse_event = 'import-progress'
if percentage == 100:
sse_event = 'last-item'
sse_data = '/home'
yield "id:{_id}\nevent:{event}\ndata:{data}\n\n".format(
_id=sse_id, event=sse_event, data=sse_data)
time.sleep(2)
return Response(import_progress(), mimetype='text/event-stream')
Обработка:
@items.route("/items/new", methods=['GET', 'POST'])
@login_required
def new_multipleitem():
form = MultipleItemForm()
if form.validate_on_submit():
pics = request.files.getlist(form.item_files.name)
if pics:
current_user.multipleupload = len(pics)
db.session.commit()
founderror=False
for pic in pics:
filename = pic.filename
try:
..... (PROGRESSING OF THE PICTURE INCLUDING CREATION OF A DATA BASE ENTRY)
return render_template('multiple_item.html', title='New Items', form=form, legend=gettext('New Items'), itemsall=itemsall, searchform=searchform)
Для завершения сценарий, кнопка и индикатор выполнения в html:
<script>
function getProgress() {
var source = new EventSource("/progress");
source.addEventListener('import-progress', function(event)
{
$('.progress-bar')
.css('width', event.data + '%')
.attr('aria-valuenow', event.data);
$('.progress-bar-label').text(event.data + '%');
}, false
);
source.addEventListener("/home", function(event)
{
source.close();
redirect(event.data);
}, false
);
}
function redirect(url) {
document.location = url;
}
...
<div class="form-group">
{{ form.submit(class="btn btn-outline-info", onclick="getProgress()") }}
</div>
.....
<div class="progress" style="width: 80%; margin: 50px;">
<div class="progress-bar progress-bar-striped active"
role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
<span class="progress-bar-label">0%</span>
</div>
</div>