Найти - Пользователи
Полная версия: Как организовать доступ и изменение данных для случая двух источников данных?
Начало » Базы данных » Как организовать доступ и изменение данных для случая двух источников данных?
1
zlodiak
У меня есть админка, она состоит из одного поля с 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)

py.user.next
zlodiak
6. В результате когда пользователь зайдёт на страничку, он получит старые данные из redis, а в это время в postgres хранятся совсем другие актуальные данные
Поэтому при чтении нужно “узнать”, в каком состоянии эти две базы. Если они синхронизированы, то он действует одним образом. Если они не синхронизированы, то он действует другим образом. Если при последней записи была ошибка записи, то он действует третим образом. Не надо сразу пытаться читать данные, если у тебя в операции записи нет операции rollback. Если запись оборвётся на середине, ничто не будет возвращено в исходное состояние, а при чтении он будет брать повреждённые данные. Так вот, либо при записи rollback должен быть какой-то, либо при чтении нужно определять, что нужно всё исправить и исправить это перед взятием данных.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB