Я пытался получить количество элементов в базах данных. Получение счета со второй базой данных работает, как и планировалось, но первая дает мне эту ошибку 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>
@Grismar Я действительно не знаю, что добавить. Единственное, что я могу сказать, что в моем методе Delete (который не упомянут выше) есть правильная строка кода (Value.query.count()), и она нормально работает для обеих баз данных. Я действительно не знаю, как описать эту проблему другими словами, потому что все на server1 и server2 одинаково, за исключением баз данных, но каким-то образом, несмотря на то, что все методы, такие как Get, Post... и count для второй базы данных, работают нормально, считать для первой просто выдает ошибку описанную выше
Это предположение, но flask использует контексты приложений для определения текущего приложения, и мне кажется, что (1) app2 является текущим приложением (последним отправленным контекстом) (2) ошибка заключается в том, что app не может быть найден. Так что, возможно, вам нужно выполнить запросы в соответствующих контекстах, а затем объединить результаты?
Тем не менее, это похоже, и проблема была с инициализацией приложения.
@snakecharmerb да, перемещение app_context прямо перед тем, как что-то делать с Value.query.count(), решило мою проблему. Может быть, вы можете сделать это сообщение, чтобы я мог отметить ваш ответ как правильный?
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)
Поскольку имена переменных и классов не имеют значения сами по себе, единственная разница между двумя сценариями, которыми вы поделились, — это значение 'sqlite:///emp2.db'. Таким образом, если нет какой-либо существенной разницы, проблема, вероятно, находится где-то в коде, который вы пропустили, и проблема не может быть воспроизведена с предоставленной вами информацией.