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))
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.
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)
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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With