AttributeError:使用flask-sqlalchemy连接到sqlite数据库时无法设置属性

Posted

技术标签:

【中文标题】AttributeError:使用flask-sqlalchemy连接到sqlite数据库时无法设置属性【英文标题】:AttributeError: can't set attribute when connecting to sqlite database with flask-sqlalchemy 【发布时间】:2021-06-13 07:08:42 【问题描述】:

我一直在学习 Flask Web 应用程序框架,对它感觉很舒服。我以前构建了一个简单易用的应用程序,效果很好。我正在从事同一个项目,但试图使用 TDD 来实现它。我遇到了一个我以前从未见过并且不知道如何修复的数据库错误。

当我检查我的代码时,我看不到任何问题。它看起来也与工作项目的代码相同,所以我真的不知道我做错了什么。

以下是错误:

(env) PS C:\coding-projects\task-master-tdd> flask shell
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:43:08) [MSC v.1926 32 bit (Intel)] on win32
App: project [development]
Instance: C:\coding-projects\task-master-tdd\instance
>>> from project import db
>>> db
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "c:\coding-projects\task-master-tdd\env\lib\site-packages\flask_sqlalchemy\__init__.py", line 1060, in __repr__
    self.engine.url if self.app or current_app else None
  File "c:\coding-projects\task-master-tdd\env\lib\site-packages\flask_sqlalchemy\__init__.py", line 943, in engine
    return self.get_engine()
  File "c:\coding-projects\task-master-tdd\env\lib\site-packages\flask_sqlalchemy\__init__.py", line 962, in get_engine
    return connector.get_engine()
  File "c:\coding-projects\task-master-tdd\env\lib\site-packages\flask_sqlalchemy\__init__.py", line 555, in get_engine
    options = self.get_options(sa_url, echo)
  File "c:\coding-projects\task-master-tdd\env\lib\site-packages\flask_sqlalchemy\__init__.py", line 570, in get_options
    self._sa.apply_driver_hacks(self._app, sa_url, options)
  File "c:\coding-projects\task-master-tdd\env\lib\site-packages\flask_sqlalchemy\__init__.py", line 914, in apply_driver_hacks
    sa_url.database = os.path.join(app.root_path, sa_url.database)
AttributeError: can't set attribute
>>>

我的 config.py 文件:

import os

# load the environment variables from the .env file
from dotenv import load_dotenv
load_dotenv()

# Determine the folder of the top-level directory of this project
BASEDIR = os.path.abspath(os.path.dirname(__file__))


class Config:
    FLASK_ENV = 'development'
    TESTING = False
    DEBUG = False
    SECRET_KEY = os.getenv('SECRET_KEY', default='A very terrible secret key.')
    SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL',
                                        default=f"sqlite:///os.path.join(BASEDIR, 'instance', 'app.db')")
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class DevelopmentConfig(Config):
    DEBUG = True

class TestingConfig(Config):
    TESTING = True
    SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL',
                                        default=f"sqlite:///os.path.join(BASEDIR, 'instance', 'test.db')")

class ProductionConfig(Config):
    FLASK_ENV = 'production'

我的用户模型:

from project import db, login_manager
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash

class User(db.Model, UserMixin):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String, unique=True)
    hashed_password = db.Column(db.String)

    def __init__(self, username, password):
        self.username = username
        self.hashed_password = generate_password_hash(password)

    def is_password_valid(self, password):
        return check_password_hash(self.hashed_password, password)

    def __repr__(self):
        return '<User >'.format(self.id)

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

【问题讨论】:

过去几天我一直在做一个项目,只是遇到了同样的错误,即使我没有修改任何重要/相关的内容。奇怪的是,当我创建一个全新的、完全独立的测试项目时,我现在遇到了同样的问题,这让我陷入了一个循环。 我突然遇到了同样的问题,没有改变任何相关的东西。也许库依赖项已更改? 【参考方案1】:

编辑

如果您遇到这种情况,将 Flask-SQLAlchemy 升级到 >= 2.5 应该可以根据 https://github.com/pallets/flask-sqlalchemy/issues/910#issuecomment-802098285 解决问题。

不再需要将 SQLAlchemy 固定到 ~1.3。


我早些时候遇到过这个问题,但我想我已经弄清楚发生了什么。

SQLAlchemy 作为 Flask-SQLAlchemy 的依赖项自动安装,其最新版本 (1.4.0) 引入了以下重大更改:

URL 对象现在是一个不可变的命名元组。要修改 URL 对象,请使用 URL.set() 方法生成新的 URL 对象。

我只需安装 SQL Alchemy (1.3.23) 的早期版本即可解决此问题。

【讨论】:

相关 github 问题跟踪修复:github.com/pallets/flask-sqlalchemy/issues/910 你拯救了我的一天 将 Flask-SQLAlchemy 升级到 >= 2.5 是解决方案。并且还在 config.py 文件中添加 '''SQLALCHEMY_DATABASE_URI = 'sqlite:///site2.db' #instead os.environ.get('SQLALCHEMY_DATABASE_URI')''' 。真是一场噩梦!【参考方案2】:

通过运行仔细检查此问题是否会影响您

pip freeze

您应该会发现当前的 sqlalchemy 版本是 1.4.0。我发现目前最快的解决方案是手动恢复到以前版本的 sqlalchemy:

pip install SQLAlchemy==1.3.23

如果您刚刚恢复到以前的版本并且它可以工作,那么现在是固定您的版本的好时机:

pip freeze > requirements.txt

【讨论】:

【参考方案3】:

确认npburns224's / SuperShoot's answer: 将Flask-SQLAlchemy(以及它的依赖项SQLAlchemy)升级到最新版本对我有用。

pip install --upgrade flask-sqlalchemy

我现在正在成功运行Flask-SQLAlchemy 2.5.1SQLAlchemy 1.4.3

【讨论】:

【参考方案4】:

我可以通过将我的sql-alchemy 版本固定到小于1.4.0 来解决此问题。上面列出了类似的例子。以下是我为解决此问题而采取的步骤,直到出现补丁。

冻结你的包裹

pip freeze > requirements.txt

在你的 requirements.txt 中更新你的SQLAlchemy

SQLAlchemy<1.4.0

重新安装软件包

pip install -r requirements.txt

有关如何执行此操作的更多信息,请参阅 pip 文档:https://pip.pypa.io/en/stable/

【讨论】:

将 SQLAlchemy 降级到 1.13.23 应该没问题,将 Flask-SQLAlchemy 升级到 2.5.1 也可以解决问题。 是的,@DaliangLYU 是正确的 flask-sqlalchemy 有一个更新可以解决这个问题。 github.com/pallets/flask-sqlalchemy/releases 了解更多信息。【参考方案5】:

刚刚遇到完全相同的错误。原来,我安装了错误的 Flask-SQLAlchemy 库。我使用 conda 而不是 pip 安装它,并且 conda 为我的操作系统和环境安装了正确的。

conda install Flask-SQLAlchemy

【讨论】:

【参考方案6】:

我通过覆盖 SQLAlchemy 类中的 apply_driver_hacks 解决了这个问题。 在这个新方法中,我删除了这一行:sa_url.database = os.path.join(app.root_path, sa_url.database)。我复制了其余的方法。

class mysqlAlchemy(SQLAlchemy):
    def apply_driver_hacks(self, app, sa_url, options):
        ...

方法可以在here找到。我描述的修复应该只是一个临时的。该问题可能会在更新版本的 flask-sqlalchemy 中得到解决。

【讨论】:

对不起,我在哪里可以找到这个方法?

以上是关于AttributeError:使用flask-sqlalchemy连接到sqlite数据库时无法设置属性的主要内容,如果未能解决你的问题,请参考以下文章

AttributeError:“字节”对象没有属性“告诉”

AttributeError:“模块”对象没有属性“WebSocketApp”

使用 Kivy 切换屏幕:AttributeError: 'NoneType' object has no attribute 'transition'

““ AttributeError”,使用python进行网络抓取

AttributeError:“QWheelEvent”对象没有属性“delta”

AttributeError:找不到 PyAudio;检查安装...无法使用语音识别