I started learning how to use SQLAlchemy for my code but for some reason when I ran the code it raised this exception:
Traceback (most recent call last):
File "C:/Users/smadar.KLAG/PycharmProjects/keylogger/site/practice.py", line 118, in <module>
db.create_all()
File "C:\Users\c\projects\test\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 1039, in create_all
self._execute_for_all_tables(app, bind, 'create_all')
File "C:\Users\c\projects\test\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 1031, in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "C:\Users\c\projects\test\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 962, in get_engine
return connector.get_engine()
File "C:\Users\c\projects\test\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 555, in get_engine
options = self.get_options(sa_url, echo)
File "C:\Users\c\projects\test\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 570, in get_options
self._sa.apply_driver_hacks(self._app, sa_url, options)
File "C:\Users\c\projects\test\venv\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
This is the code:
from flask import Flask, redirect, url_for, render_template, request, session, flash
from time import sleep
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
class Users(db.Model):
_id = db.Column("id", db.Integer, primary_key=True)
email = db.Column(db.String(100))
password = db.Column(db.String(100))
if __name__ == '__main__':
db.create_all()
app.run(debug=True)
I tried running the code of a friend of mine that has SQLAlchemy (the code does work for him) incase it was a coding issue but I have reached the same error with his code as well.
Is there something I am doing incorrectly?
I just ran into this too. Looks like SQLAlchemy just released version 1.4, which breaks flask_sqlalchemy.
I was able to resolve the issue on my system by installing the previous (1.3) version instead.
EDIT: the latest version of SQLAlchemy works now (version 1.4 as of writing this)
installing SQLAlchemy 1.3.23 worked for me.
pip install SQLAlchemy==1.3.23
Related
When I run
heroku run python
>>> from app.main import app
>>> app.config['SQLALCHEMY_DATABASE_URI']
'postgres://<url string>' # the database url is passed correctly
>>> from app.main import db
>>> db.create_all()
it gives this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 1039, in create_all
self._execute_for_all_tables(app, bind, 'create_all')
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 1031, in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 962, in get_engine
return connector.get_engine()
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 556, in get_engine
self._engine = rv = self._sa.create_engine(sa_url, options)
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 972, in create_engine
return sqlalchemy.create_engine(sa_url, **engine_opts)
File "<string>", line 2, in create_engine
File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/util/deprecations.py", line 298, in warned
return fn(*args, **kwargs)
File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/engine/create.py", line 520, in create_engine
entrypoint = u._get_entrypoint()
File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/engine/url.py", line 653, in _get_entrypoint
cls = registry.load(name)
File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 342, in load
"Can't load plugin: %s:%s" % (self.group, name)
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres
I'm confused because I'm new to Heroku and Postgresql (been using SQLite until now) and none of the tutorials I'm following explain how it all connects to Flask, only how to do it. So I don't understand what to look at to fix the problem. Is there any other code I should include in the question?
(Most of the other questions like this one are typos or errors that don't fix this issue.)
This is due to a change in the sqlalchemy library. It was an announced deprecation in the changing of the dialect (the part before the ':' in the SQLALCHEMY_DATABASE_URI) name postgres to postgresql. They released this breaking change from this github commit with a minor version release, which is in their policy to do so.
Heroku's default dialect is postgres in the DATABASE_URL they provide, which gets translated into the SQLALCHEMY_DATABASE_URI. Heroku could update their postgres add-on if updating does not break other libraries which might depend on it.
In the meantime, you can pin your sqlalchemy library back to <1.4.0 (1.3.23 is the last 1.3.x release), and it should work.
Alternatively, you can update your code to modify the dialect.
Here's a quick one that works for me, with the latest PostgreSQL on Heroku:
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL').replace("://", "ql://", 1)
Just hacks the postgres:// from Heroku (which can't be edited) to postgresql://.
I have used sql-alchemy for so long but I don't know it suddnly stopped working and showing me errors
Code
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# create the extension
db = SQLAlchemy()
# create the app
app = Flask(__name__)
# configure the SQLite database, relative to the app instance folder
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
# initialize the app with the extension
db.init_app(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, unique=True, nullable=False)
email = db.Column(db.String)
with app.app_context():
db.create_all()
this is code available on sqlalchemy documentation
Error
(venv) viral#viral-Lenovo:~/Desktop/sql-practice$ python main.py
Traceback (most recent call last):
File "/home/viral/Desktop/sql-practice/main.py", line 11, in <module>
db.init_app(app)
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/flask_sqlalchemy/extension.py", line 326, in init_app
engines[key] = self._make_engine(key, options, app)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/flask_sqlalchemy/extension.py", line 614, in _make_engine
return sa.engine_from_config(options, prefix="")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/sqlalchemy/engine/create.py", line 817, in engine_from_config
return create_engine(url, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<string>", line 2, in create_engine
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/sqlalchemy/util/deprecations.py", line 277, in warned
return fn(*args, **kwargs) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/sqlalchemy/engine/create.py", line 605, in create_engine
dbapi = dbapi_meth(**dbapi_args)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/sqlalchemy/dialects/sqlite/pysqlite.py", line 504, in import_dbapi
from sqlite3 import dbapi2 as sqlite
File "/usr/local/lib/python3.11/sqlite3/__init__.py", line 57, in <module>
from sqlite3.dbapi2 import *
File "/usr/local/lib/python3.11/sqlite3/dbapi2.py", line 27, in <module>
from _sqlite3 import *
ModuleNotFoundError: No module named '_sqlite3'
I expected that it will create a database by creating new folder called instance. but it's only creating instance folder but not database
I have tried creating new venv, reinstalling python and restarting pc but still it's showing the same error.
note: I am using Linux, Ubuntu Kde plasma
I've been having a hard time handling sessions in flask. Since when I manage the application in the local environment everything works perfectly, including flask sessions. But when i already host it in Render i always get this error in every route.
[55] [ERROR] Error handling request /valle-de-guadalupe
Traceback (most recent call last):
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/app.py", line 2525, in wsgi_app
response = self.full_dispatch_request()
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/app.py", line 1822, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/opt/render/project/src/app_folder/routes/public.py", line 35, in valle_de_guadalupe
return render_template("public/cities/valle_guadalupe.html")
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/templating.py", line 147, in render_template
return _render(app, template, context)
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/templating.py", line 128, in _render
app.update_template_context(context)
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/app.py", line 994, in update_template_context
context.update(func())
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask_login/utils.py", line 407, in _user_context_processor
return dict(current_user=_get_user())
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask_login/utils.py", line 372, in _get_user
current_app.login_manager._load_user()
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask_login/login_manager.py", line 364, in _load_user
user = self._user_callback(user_id)
File "/opt/render/project/src/app.py", line 52, in load_user
return User.get_by_id(int(user_id))
File "/opt/render/project/src/app_folder/models/models.py", line 82, in get_by_id
return User.query.get(id)
File "<string>", line 2, in get
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/sqlalchemy/util/deprecations.py", line 402, in warned
return fn(*args, **kwargs)
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/sqlalchemy/orm/query.py", line 947, in get
return self._get_impl(ident, loading.load_on_pk_identity)
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/sqlalchemy/orm/query.py", line 959, in _get_impl
execution_options=self._execution_options,
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2959, in _get_impl
load_options=load_options,
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/sqlalchemy/orm/loading.py", line 534, in load_on_pk_identity
bind_arguments=bind_arguments,
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 1702, in execute
bind = self.get_bind(**bind_arguments)
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask_sqlalchemy/session.py", line 61, in get_bind
engines = self._db.engines
File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask_sqlalchemy/extension.py", line 629, in engines
return self._app_engines[app]
File "/usr/local/lib/python3.7/weakref.py", line 396, in __getitem__
return self.data[ref(key)]
KeyError: <weakref at 0x7fc9e8267ad0; to 'Flask' at 0x7fc9e9ec5750>
index.py
from app import app
from app_folder.utils.db import db
db.init_app(app)
with app.app_context():
db.create_all()
if __name__ == "__main__":
app.run(
debug = False,
port = 5000
)
app.py
from flask import Flask
"""Flask SqlAlchemy"""
from flask_sqlalchemy import SQLAlchemy
"""Flask Login"""
from flask_login import LoginManager
"""Dot Env"""
from dotenv import load_dotenv
"""App Folder Routes"""
from app_folder.handlers.stripe_handlers import stripe_error
from app_folder.handlers.web_handlers import web_error
from app_folder.models.models import User
from app_folder.routes.admin import admin
from app_folder.routes.public import public
from app_folder.routes.users import users
from app_folder.utils.db import db
"""Imports"""
import os
import stripe
load_dotenv()
"""config app"""
app = Flask(__name__,
static_url_path="",
template_folder="app_folder/templates",
static_folder="app_folder/static")
app.config['SECRET_KEY'] = os.getenv("SECRET_KEY")
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv("SQLALCHEMY_DATABASE_VERSION")+os.getenv("SQLALCHEMY_USERNAME")+":"+os.getenv("SQLALCHEMY_PASSWORD")+"#"+os.getenv("SQLALCHEMY_SERVER")+"/"+os.getenv("SQLALCHEMY_DATABASE")
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = os.getenv("SQLALCHEMY_TRACK_MODIFICATIONS")
"""blueprints"""
app.register_blueprint(stripe_error)
app.register_blueprint(web_error)
app.register_blueprint(admin)
app.register_blueprint(public)
app.register_blueprint(users)
SQLAlchemy(app)
login_manager = LoginManager(app)
""" stripe """
stripe_keys = {
'secret_key': os.getenv("STRIPE_SECRET_KEY"),
'publishable_key': os.getenv("STRIPE_PUBLISHABLE_KEY")
}
stripe.api_key = stripe_keys['secret_key']
"""Login Manager"""
#login_manager.user_loader
def load_user(user_id):
return User.get_by_id(int(user_id))
"""Teardown"""
#app.teardown_appcontext
def shutdown_session(exception=None):
db.session.remove()
Regardless of which route i'm on, while handling sessions I get the same error, but in this case use this path.
public.py
"""routes"""
#public.route("/", methods=["GET", "POST"])
def index():
return redirect(url_for('public.valle_de_guadalupe'))
"""cities"""
#public.route("/valle-de-guadalupe", methods=["GET", "POST"])
def valle_de_guadalupe():
return render_template("public/cities/valle_guadalupe.html")
I don't know if this has happened to someone else.
It's usually best to remove as many extra components and identify a minimal example that produces the error, otherwise it's often hard to help.
That said, I think that error suggests that db (SQLAlachemy() from flask-sqlalchemy) is not being inited with app.
I'm not sure what the db is that is being imported from app_folder.utils.db, but it appears that you may need to call db.init_app(app).
Relatedly, the line SQLAlchemy(app) is not being assigned. Perhaps you meant to assign that to db?
Other people report that this issue happens since the upgrade from flask-sqlalchemy v2.5.1 to v3. So downgrading might be a work around (not a permanent solution)
Source
When I run
heroku run python
>>> from app.main import app
>>> app.config['SQLALCHEMY_DATABASE_URI']
'postgres://<url string>' # the database url is passed correctly
>>> from app.main import db
>>> db.create_all()
it gives this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 1039, in create_all
self._execute_for_all_tables(app, bind, 'create_all')
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 1031, in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 962, in get_engine
return connector.get_engine()
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 556, in get_engine
self._engine = rv = self._sa.create_engine(sa_url, options)
File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 972, in create_engine
return sqlalchemy.create_engine(sa_url, **engine_opts)
File "<string>", line 2, in create_engine
File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/util/deprecations.py", line 298, in warned
return fn(*args, **kwargs)
File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/engine/create.py", line 520, in create_engine
entrypoint = u._get_entrypoint()
File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/engine/url.py", line 653, in _get_entrypoint
cls = registry.load(name)
File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 342, in load
"Can't load plugin: %s:%s" % (self.group, name)
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres
I'm confused because I'm new to Heroku and Postgresql (been using SQLite until now) and none of the tutorials I'm following explain how it all connects to Flask, only how to do it. So I don't understand what to look at to fix the problem. Is there any other code I should include in the question?
(Most of the other questions like this one are typos or errors that don't fix this issue.)
This is due to a change in the sqlalchemy library. It was an announced deprecation in the changing of the dialect (the part before the ':' in the SQLALCHEMY_DATABASE_URI) name postgres to postgresql. They released this breaking change from this github commit with a minor version release, which is in their policy to do so.
Heroku's default dialect is postgres in the DATABASE_URL they provide, which gets translated into the SQLALCHEMY_DATABASE_URI. Heroku could update their postgres add-on if updating does not break other libraries which might depend on it.
In the meantime, you can pin your sqlalchemy library back to <1.4.0 (1.3.23 is the last 1.3.x release), and it should work.
Alternatively, you can update your code to modify the dialect.
Here's a quick one that works for me, with the latest PostgreSQL on Heroku:
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL').replace("://", "ql://", 1)
Just hacks the postgres:// from Heroku (which can't be edited) to postgresql://.
I'm building an API service with Flask, SQLAlchemy and more recently integrating the Flask-SQLAlchemy extension. While I can run the app standalone and make API calls successfully, I am hitting a problem attempting to run unittests. I believe the issue is with importing the db.Model types more than once.
The exception is this:
Error
Traceback (most recent call last):
File "/Users/james/.pyenv/versions/2.7.10/lib/python2.7/unittest/case.py", line 322, in run
self.setUp()
File "/Users/james/Documents/workspace/trustmile-backend/trustmile/tests/test_users.py", line 28, in setUp
from trustmile.app.users.model import User, ConsumerUser, CourierUser, AuthSession, Location, UserAddress, db
File "/Users/james/Documents/workspace/trustmile-backend/trustmile/app/users/model.py", line 23, in <module>
class User(db.Model, UniqueMixin, TableColumnsBase, References):
File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 536, in __init__
DeclarativeMeta.__init__(self, name, bases, d)
File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", line 55, in __init__
_as_declarative(cls, classname, cls.__dict__)
File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 88, in _as_declarative
_MapperConfig.setup_mapping(cls, classname, dict_)
File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 103, in setup_mapping
cfg_cls(cls_, classname, dict_)
File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 131, in __init__
self._setup_table()
File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 394, in _setup_table
**table_kw)
File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 398, in __new__
"existing Table object." % key)
InvalidRequestError: Table 'tmuser' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
My init.py in /app/ (the top level) is like this:
__author__ = 'james'
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
import config
from app.messaging import EmailHandler
app = Flask(__name__, static_folder='api/static', static_url_path='/static')
app.config.from_object(config)
db = SQLAlchemy(app)
EmailHandler.setup(config.EMAIL_API_KEY_DEV)
from app.api.consumer_v1 import bp as blueprint
app.register_blueprint(blueprint, url_prefix = '/consumer/v1')
app.test_request_context()
Running that with:
from app import app
app.run(debug=True, host='0.0.0.0', port=5001)
Works great.
The beginning of my test_users.py looks like this:
__author__ = 'james'
from trustmile.app.exc import InvalidEmailException
from trustmile.app.exc import InsecurePasswordException
from nose.tools import assert_true, raises
from trustmile.app.users.model import User, ConsumerUser, CourierUser, AuthSession, Location, UserAddress, db
from . import TransactionalTest
email_address = 'james#cloudadvantage.com.au'
test_password = 'mypassword'
class UserTest(TransactionalTest):
#classmethod
def setUpClass(cls):
super(UserTest, cls).setUpClass()
def setUp(self):
super(UserTest, self).setUp()
def test_create_user(self):
user = User()
db.session.add(user)
It must be fairly common way to do unit testing and yes I'm sharing the SQLAlchemy object between modules (which I'm sure is bad practice). I'm running it with nosetests and the error occurs as the code is initialised. Sorry for the lengthy question, hopefully someone can help me!
__table_args__ = {'extend_existing': True}
right below __tablename__