Форум сайта python.su
У меня есть админка, она состоит из одного поля с id=“notepad”. Из набора CRUD доступны только операции чтения и изменения.
Для хранения данных используются: redis, postgres
Чтение:
1. Пользователь открывает страничку админки.
2. Уходит запрос значения notepad в redis
3. Если данные приходят из redis, то отрисовывается страничка админки
4. Если данные из redis не приходят, то уходит запрос в postgres
5. Если данные из postgres приходят, то отрисовывается страничка админки
6. Если данные из postgres не приходят, то всё равно отрисовывается страничка админки, но с пустым полем notepad
Обновление:
1. Пользователь заполняет поле notepad
2. Данные записываются в redis
3. Данные записываются в postgres
Мне кажется, в операции записи я произвожу лишние действия. Видио, нужно поставить какое-нибудь условие. Но я не понимаю как это сделать. Помогите пожалуйста.
В частности беспокоит меня такой кейс:
1. В redis есть данные для поля notepad
2. В postgres есть те же данные для поля notepad
3. Пользователь записывает новые данные в это поле.
4. В redis не успешно
5. В postgres успешно
6. В результате когда пользователь зайдёт на страничку, он получит старые данные из redis, а в это время в postgres хранятся совсем другие актуальные данные
Вот репозиторий: https://github.com/zlodiak/flask_adminka_with_redis
Обновление данных происходит здесь: https://github.com/zlodiak/flask_adminka_with_redis/blob/master/app.py#L111
Чтение данных происходит здесь: https://github.com/zlodiak/flask_adminka_with_redis/blob/master/app.py#L20
или, если так удобнее, то:
Обновление:
@app.route('/submit_notepad_request', methods=['POST']) def submit_notepad_request(): with DB_connection() as db_connect: notepad = request.values.get('notepad') id_auth_user = request.cookies.get('flask_adminka_authorized_user_id') with redis_instance.pipeline() as pipe: pipe.multi() pipe.set('notepad:' + id_auth_user, notepad) pipe.execute() redis_instance.bgsave() db_cursor = db_connect.cursor() req = "select * from options where user_id=" + id_auth_user db_cursor.execute(req) record = db_cursor.fetchone() if record: try: req = "UPDATE options SET notepad='" + notepad + "' WHERE user_id=" + str(id_auth_user) db_cursor.execute(req); db_connect.commit() resp = Response('submit notepad is complete') return resp except: resp = Response('failed') return resp
@app.route('/admin') def admin(): if 'flask_adminka_authorized_user_id' not in request.cookies: return redirect('/', code=404) id_auth_user = request.cookies.get('flask_adminka_authorized_user_id') admin_forms_values = { 'firstname': None, 'lastname': None, 'notepad': None, } firstname = redis_instance.get('firstname:' + id_auth_user) lastname = redis_instance.get('lastname:' + id_auth_user) notepad = redis_instance.get('notepad:' + id_auth_user) if firstname and lastname and notepad: admin_forms_values['firstname'] = firstname.decode("utf-8") admin_forms_values['lastname'] = lastname.decode("utf-8") admin_forms_values['notepad'] = notepad.decode("utf-8") return render_template('admin.html', admin_forms_values=admin_forms_values) with DB_connection() as db_connect: db_cursor = db_connect.cursor() try: request_form = "select * from options where user_id='" + id_auth_user + "'" db_cursor.execute(request_form) record = db_cursor.fetchone() admin_forms_values['firstname'] = record[1] if record[1] else '' admin_forms_values['lastname'] = record[2] if record[2] else '' admin_forms_values['notepad'] = record[3] if record[3] else '' print('log: successfull retrieve admin_forms_values', admin_forms_values) except: print('log: failed retrieve admin_forms_values', admin_forms_values) return render_template('admin.html', admin_forms_values=admin_forms_values)
Офлайн
zlodiakПоэтому при чтении нужно “узнать”, в каком состоянии эти две базы. Если они синхронизированы, то он действует одним образом. Если они не синхронизированы, то он действует другим образом. Если при последней записи была ошибка записи, то он действует третим образом. Не надо сразу пытаться читать данные, если у тебя в операции записи нет операции rollback. Если запись оборвётся на середине, ничто не будет возвращено в исходное состояние, а при чтении он будет брать повреждённые данные. Так вот, либо при записи rollback должен быть какой-то, либо при чтении нужно определять, что нужно всё исправить и исправить это перед взятием данных.
6. В результате когда пользователь зайдёт на страничку, он получит старые данные из redis, а в это время в postgres хранятся совсем другие актуальные данные
Отредактировано py.user.next (Дек. 7, 2019 05:39:52)
Офлайн