Почему второе Flask-приложение не может получить новые данные из одной базы данных и возникает ошибка?

Как можно организовать взаимодействие между двумя Flask приложениями, находящимися на разных машинах, которые используют одну и ту же базу данных, при условии, что код инициализации и модели в обоих приложениях идентичен? Вот пример кода для инициализации Flask приложения и определения модели базы данных, а также для добавления записи и чтения данных из двух разных приложений. 

Пример инициализации Flask приложения:
```python
app = Flask(__name__)
app.secret_key = KEY
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=12)
if __name__ == '__main__':
    app.run()
```

Пример модели базы данных:
```python
class Calls(base):
    __tablename__ = 'calls'
    id = Column(Integer, primary_key=True)
    creator = Column(String)
    partname = Column(String)
    calls_date = Column(DateTime)
```

Пример добавления записи через SQLAlchemy в первом Flask приложении:
```python
new_call = Calls(calls_date=datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
                 creator=current_user.fio,
                 partname=request.form.get("partname"))
session.add(new_call)
session.commit()
calls_data = session.query(Calls).order_by(Calls.id.desc()).all()
return render_template("calls_default.html", calls_data=calls_data)
```

Данные добавляются в базу данных, при этом уникальный порядковый id записи автоматически присваивается на уровне базы данных. После этого обновленные данные, включая этот id записи, возвращаются на HTML страницу.

Пример чтения данных через второе Flask приложение спустя какое-то время:
```python
calls_data = session.query(Calls).order_by(Calls.id.desc()).all()
return render_template("calls_default.html", calls_data=calls_data)
```
  • 3 сентября 2024 г. 18:53
Ответы на вопрос 2
Ошибка, с которой вы мог столкнуться во втором Flask-приложении при попытке чтения данных из базы данных, может быть вызвана различными причинами. Вот некоторые из возможных проблем и решения:

### Возможные причины проблемы

1. **Кэширование**: Если оба приложения используют кэширование, то второе приложение может возвращать старые данные. Это можно устранить, изменив настройки кэширования или отключив его, как в вашем случае с `SEND_FILE_MAX_AGE_DEFAULT`.

2. **Проблемы с сессиями**: Убедитесь, что оба приложения настраиваются на одно и то же управление соединениями с базой данных. Если они используют разные сессии, возможно, требуется ручное обновление клиентского кэша.

3. **Отдельные подключения к базе данных**: Если оба приложения используют разные соединения для доступа к одной базе данных, убедитесь, что соединения правильно закрываются и работают.

4. **Асинхронность**: Если одно приложение добавляет, а другое считывает данные одновременно, можно столкнуться с состоянием гонки или несогласованными данными. Это может быть устранено путём применения замков.

### Рекомендации по организации взаимодействия

Чтобы организовать взаимодействие между двумя Flask-приложениями, использующими одну и ту же базу данных, выполните следующие шаги:

1. **Настройка базы данных**: Убедитесь, что оба приложения правильно настроены на использование одной и той же базы данных. Проверьте параметры подключения.

2. **Обновление данных**: После добавления новой записи в первом приложении попробуйте явным образом уведомить второе приложение об обновлении данных. Например, можно использовать очереди задач (например, `Celery`) или HTTP-запросы для уведомления о новых данных.

3. **Регулярные обновления**: Реализуйте возможность периодического обновления данных во втором приложении. Например, обновляйте данные каждую минуту с помощью фонового задания.

4. **Журналирование запросов**: Добавьте несколько логов в первичное приложение, чтобы точно знать, что данные добавляются, и регистрируйте любые ошибки.

5. **Обработка ошибок**: Убедитесь, что у вас есть обработка ошибок, чтобы отлавливать ошибки при считывании данных. Это поможет вам лучше понять, что идет не так, если возникает ошибка.

6. **Гарантия целостности данных**: Используйте методы оптимистической или пессимистической блокировки для предотвращения конфликтов.

### Пример кода

Вот небольшой пример кода, который показывает, как два Flask-приложения могут взаимодействовать с одной и той же базой данных, избегая кэширования:

**Первый Flask-приложение (добавление данных):**
```python
new_call = Calls(calls_date=datetime.now(),
                 creator=current_user.fio,
                 partname=request.form.get("partname"))
session.add(new_call)
session.commit()
# Уведомить о обновлении (например, через HTTP-запрос)
```

**Второе Flask-приложение (чтение данных):**
```python
@app.route('/get_calls', methods=['GET'])
def get_calls():
    calls_data = session.query(Calls).order_by(Calls.id.desc()).all()
    return render_template("calls_default.html", calls_data=calls_data)
```

При этом важно следить за тем, чтобы обновленные данные были доступны для второго приложения. Возможно, стоит использовать дополнительные средства для синхронизации данных между приложениями, в зависимости от ваших требований.
Попробуйте сессию инициализировать в обработчике роутера через отдельный метод (еще лучше использовать DI) 
что-то типа такого:
def get_session():
    with Session() as session:
        yield session
        session.commit()
        session.close()


и уже в обработчике роута вызывать
session = get_session()
calls_data = session.query(Calls).order_by(Calls.id.desc()).all()
return render_template("calls_default.html", calls_data=calls_data)
Похожие вопросы