SQLAlchemy: TypeError: MetaData.__init__() получил неожиданный аргумент ‘bind’

Вопрос или проблема

Немного предыстории: я довольно нов в SQLAlchemy, поэтому изучал документацию, пытаясь найти способ выполнять запросы к уже существующей базе данных MariaDB в Flask-SQLAlchemy. Это привело меня к этому: документу SQLAlchemy в Flask, который, казалось, отвечал на мой точный вопрос. Я сделал небольшой проект на основе раздела “Декларативный”, а затем изменил его для раздела “Абстракция SQL”, в результате чего получились следующие файлы и структура файлов:

  • sql_abstract
    • .venv

    • app

      • _init_.py
      • database.py
      • models.py
      • routes.py
    • config.py

    • run.py

_init_.py

from flask import Flask

def create_app():
    app = Flask(__name__)
    app.config.from_object('config')

    from app.routes import register_routes
    register_routes(app)

    return app

database.py

from sqlalchemy import create_engine, MetaData, Table
from config import conf

engine=create_engine(conf)
metadata = MetaData(bind=engine)

models.py

from sqlalchemy import Table
from app.database import metadata

basic = Table('tblBasic', metadata, autoload=True)

routes.py

from app.models import basic

def register_routes(app):
    @app.route("https://stackoverflow.com/")
    def index():
        res= basic.select(basic.c.name == "John").execute().first()
        return res

run.py

#get the app from the app folder's init.py
from app import create_app

flask_app=create_app()
if __name__ == '__main__':
    flask_app.run()

Это приводит к следующей ошибке:

File "c:\...\app\database.py", line 5, in <module>
    metadata = MetaData(bind=engine)
               ^^^^^^^^^^^^^^^^^^^^^
TypeError: MetaData.__init__() got an unexpected keyword argument 'bind'

Я в замешательстве, и потому что это код из документации, но также в документации SQLAlchemy упоминается, что Metadata “Содержит коллекцию Table объектов, а также необязательное связывание с Engine или Connection.”

Я пытался импортировать специально из sqlalchemy.schema, думая, что могу импортировать другой класс с таким же именем, но это не сработало.
Я также пробовал использовать Metadata.reflect(bind=engine) как в этом примере, в результате чего строка 5 в database.py стала:

metadata = MetaData().reflect(bind=engine)

а строка 4 в models.py стала:

basic=metadata.tables["tblBasic"]

но это привело к тому, что metadata стал объектом типа NoneType.

Кто-нибудь знает, что вызывает эту ошибку и как это исправить? Я в полном замешательстве.

Ответ или решение

Ошибка TypeError: MetaData.__init__() got an unexpected keyword argument 'bind' в SQLAlchemy может возникнуть по нескольким причинам, однако, в контексте вашего кода, проблема заключается в том, как вы инициализируете объект MetaData.

Причины ошибки

  1. Версия SQLAlchemy: В вашем коде используется параметр bind при инициализации объекта MetaData, который был актуален в старых версиях SQLAlchemy. С версии 1.4 и новее, параметр bind был удален из конструктора MetaData. Вместо этого, необходимо использовать методы подсоединения к движку (engine) напрямую.

  2. Подход к работе с метаданными: В новых версиях SQLAlchemy рекомендуется использовать MetaData с методами для отражения структуры базы данных, например reflect(), без передачи параметров конструкции.

Как исправить

Для исправления вашей ошибки, вам нужно изменить способ инициализации объекта MetaData в файле database.py. Вместо использования параметра bind, выполните сравнение вашей версии SQLAlchemy с документацией и измените код на следующий:

from sqlalchemy import create_engine, MetaData

from config import conf

engine = create_engine(conf)
metadata = MetaData()  # Убираем bind=engine здесь

# Далее необходимо отразить метаданные
metadata.reflect(bind=engine)  # Теперь вы можете использовать этот метод

Убедитесь, что в вашем файле models.py вы обращаетесь к таблице правильно. Измените его следующим образом:

from sqlalchemy import Table

from app.database import metadata

basic = metadata.tables["tblBasic"]  # Теперь вы берете таблицу из обновленного metadata

Дополнительные Примечания

  1. Проверка версии: Соответственно проверьте версию SQLAlchemy, установленную в вашем виртуальном окружении. Это можно сделать, выполнив команду:

    pip show SQLAlchemy
  2. Понимание изменений в API: Всегда полезно ознакомиться с историей изменений (changelog) библиотеки, чтобы понять какие изменения могут касаться того, что вы пытаетесь сделать.

Заключение

Таким образом, вам следует обновить ваш код с учетом современных стандартов SQLAlchemy. Изменения, предложенные выше, должны решить вашу проблему с TypeError и позволяют вам правильно работать с метаданными базы данных. Убедитесь, что ваш код соответствует последним рекомендациям в документации SQLAlchemy для предотвращения подобных ошибок в будущем.

Оцените материал
Добавить комментарий

Капча загружается...