Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AttributeError: can't set attribute when connecting to sqlite database with flask-sqlalchemy

I've been learning the flask web application framework and feel quite comfortable with it. I've previously built a simple to do app that worked perfectly. I was working on the same project, but trying to implement it using TDD. I've encountered an error with the database that I've never seen before and don't know how to fix.

When I examine my code, I cant see any issue. It also looks identical to the code of the working project, so I really don't know what I am doing wrong.

Here is the errors:

(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 >>> 

my config.py file:

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' 

my user model:

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)) 
like image 223
Ange Uwase Avatar asked Mar 16 '21 01:03

Ange Uwase


People also ask

How do I connect to a SQLite database using flask?

You make a Flask application instance called app. You define a function called get_db_connection (), which opens a connection to the database.db database file you created earlier, and sets the row_factory attribute to sqlite3.Row so you can have name-based access to columns.

What are some Common flask-SQLAlchemy errors?

Flask-SQLAlchemy AttributeError: can't set attribute -2 Flask SQLAlchemy can't set attribute error in a venv 0 Flask-SQLAlchemy: 'AttributeError: can't set attribute' after changing sd Card of raspberryPie 0 AttributeError: can't set attribute (with flask framework)

How to create a SQLite database using SQLAlchemy?

In your app.py file import SQLAlchemy as shown in the below code. We also need to add a configuration setting to our application so that we can use SQLite database in our application. We also need to create an SQLAlchemy database instance which is as simple as creating an object. In sqlalchemy we use classes to create our database structure.

How do I use SQLAlchemy with flask?

After configuring SQLAlchemy by setting a database URI and disabling tracking, you create a database object using the SQLAlchemy class, passing the application instance to connect your Flask application with SQLAlchemy. You store your database object in a variable called db. You’ll use this db object to interact with your database.


Video Answer


1 Answers

Edit

If you're experiencing this, upgrading Flask-SQLAlchemy to >= 2.5 should resolve the issue per https://github.com/pallets/flask-sqlalchemy/issues/910#issuecomment-802098285.

Pinning SQLAlchemy to ~1.3 should no longer be necessary.


I ran into this issue a little earlier, but think I've figured out what's going on.

SQLAlchemy is automatically installed as a dependency for Flask-SQLAlchemy and its latest release (1.4.0) introduces the following breaking change:

The URL object is now an immutable named tuple. To modify a URL object, use the URL.set() method to produce a new URL object.

I was able to fix this issue by simply installing the previous version of SQL Alchemy (1.3.23).

like image 78
npburns224 Avatar answered Sep 20 '22 13:09

npburns224