Странная ошибка при попытке получить данные из базы данных в другой файл

Я пытался получить количество элементов в базах данных. Получение счета со второй базой данных работает, как и планировалось, но первая дает мне эту ошибку KeyError: <weakref at 0x000001E85C863330; to "Flask" at 0x000001E8397750D0> Эта программа очень упрощена, но удаленные элементы работают нормально (методы Get, Post, Delete...)

Итак, у меня есть 3 файла сервер1:

app = Flask(__name__)

api = Api(app)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///emp.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

class Value(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    value = db.Column(db.Integer, nullable=False)

class GetCount(Resource):
    @staticmethod
    def count():
        count = Value.query.count()
        return count

Сервер2:

app2 = Flask(__name__)

api2 = Api(app2)

app2.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///emp2.db'
app2.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db2 = SQLAlchemy(app2)


class Value2(db2.Model):
    id = db2.Column(db2.Integer, primary_key=True)
    value = db2.Column(db2.Integer, nullable=False)

class GetCount2(Resource):
    @staticmethod
    def count():
        count = Value2.query.count()
        return count

Мастернода:

import time
from server1 import app, Value
from server2 import app2, Value2

app.app_context().push()
app2.app_context().push()

while True:
    c = Value.query.count()
    c2 = Value2.query.count()
    print(c, c2)
    time.sleep(1)

Я пытался запустить эту программу, но получил ошибку, упомянутую выше. Но когда я удалил c = Value.query.count() из файла мастерноды я получил ожидаемый результат (1 1 1 1 и т. д.)

Так что я действительно не понимаю, почему одна программа работает, а другая нет, когда они практически одинаковы

Полная трассировка ошибок:


Traceback (most recent call last):
  File "C:\Users\Sergio\Desktop\Домашка\FlaskTest\masternode.py", line 15, in <module>
    c1 = Value.query.count()
         ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Sergio\AppData\Local\Programs\Python\Python311\Lib\site-packages\sqlalchemy\orm\query.py", line 3175, in count
    return self._from_self(col).enable_eagerloads(False).scalar()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Sergio\AppData\Local\Programs\Python\Python311\Lib\site-packages\sqlalchemy\orm\query.py", line 2892, in scalar
    ret = self.one()
          ^^^^^^^^^^
  File "C:\Users\Sergio\AppData\Local\Programs\Python\Python311\Lib\site-packages\sqlalchemy\orm\query.py", line 2869, in one
    return self._iter().one()
           ^^^^^^^^^^^^
  File "C:\Users\Sergio\AppData\Local\Programs\Python\Python311\Lib\site-packages\sqlalchemy\orm\query.py", line 2915, in _iter
    result = self.session.execute(
             ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Sergio\AppData\Local\Programs\Python\Python311\Lib\site-packages\sqlalchemy\orm\session.py", line 1702, in execute
    bind = self.get_bind(**bind_arguments)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Sergio\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask_sqlalchemy\session.py", line 61, in get_bind
    engines = self._db.engines
              ^^^^^^^^^^^^^^^^
  File "C:\Users\Sergio\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask_sqlalchemy\extension.py", line 629, in engines
    return self._app_engines[app]
           ~~~~~~~~~~~~~~~~~^^^^^
  File "C:\Users\Sergio\AppData\Local\Programs\Python\Python311\Lib\weakref.py", line 415, in __getitem__
    return self.data[ref(key)]
           ~~~~~~~~~^^^^^^^^^^
KeyError: <weakref at 0x000001E85C863330; to 'Flask' at 0x000001E8397750D0>

Поскольку имена переменных и классов не имеют значения сами по себе, единственная разница между двумя сценариями, которыми вы поделились, — это значение 'sqlite:///emp2.db'. Таким образом, если нет какой-либо существенной разницы, проблема, вероятно, находится где-то в коде, который вы пропустили, и проблема не может быть воспроизведена с предоставленной вами информацией.

Grismar 21.11.2022 01:23

@Grismar Я действительно не знаю, что добавить. Единственное, что я могу сказать, что в моем методе Delete (который не упомянут выше) есть правильная строка кода (Value.query.count()), и она нормально работает для обеих баз данных. Я действительно не знаю, как описать эту проблему другими словами, потому что все на server1 и server2 одинаково, за исключением баз данных, но каким-то образом, несмотря на то, что все методы, такие как Get, Post... и count для второй базы данных, работают нормально, считать для первой просто выдает ошибку описанную выше

Sergio 21.11.2022 01:33

Это предположение, но flask использует контексты приложений для определения текущего приложения, и мне кажется, что (1) app2 является текущим приложением (последним отправленным контекстом) (2) ошибка заключается в том, что app не может быть найден. Так что, возможно, вам нужно выполнить запросы в соответствующих контекстах, а затем объединить результаты?

snakecharmerb 21.11.2022 09:02

Тем не менее, это похоже, и проблема была с инициализацией приложения.

snakecharmerb 21.11.2022 09:11

@snakecharmerb да, перемещение app_context прямо перед тем, как что-то делать с Value.query.count(), решило мою проблему. Может быть, вы можете сделать это сообщение, чтобы я мог отметить ваш ответ как правильный?

Sergio 21.11.2022 12:00
Мутабельность и переработка объектов в Python
Мутабельность и переработка объектов в Python
Объекты являются основной конструкцией любого языка ООП, и каждый язык определяет свой собственный синтаксис для их создания, обновления и...
Другой маршрут в Flask Python
Другой маршрут в Flask Python
Flask - это фреймворк, который поддерживает веб-приложения. В этой статье я покажу, как мы можем использовать @app .route в flask, чтобы иметь другую...
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
Проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
Почему Python - идеальный выбор для проекта AI и ML
Почему Python - идеальный выбор для проекта AI и ML
Блог, которым поделился Harikrishna Kundariya в нашем сообществе Developer Nation Community.
1
5
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Flask использует контексты приложения для определения текущего приложения, поэтому запросы для разных приложений должны выполняться в соответствующих контекстах.

Что-то вроде этого должно работать:

while True:
    with app.app_context():
        c = Value.query.count()
    with app2.app_context:
        c2 = Value2.query.count()
    print(c, c2)
    time.sleep(1)

Другие вопросы по теме