It is the first time when I am using SQLAlchemy with sqllight.
My code looks like this:
#we are going to create the flask app
app = Flask(__name__)
global db
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqllite:///databse.db'
app.config['SECRET_KEY'] = 'ca8b6694c31960d1f7ee2d1ac73c669f'
db = SQLAlchemy(app)
app = create_app()
The next step is to go the terminal and type python. The python interpreter will come and I typed "from main import db", since my file is called main I have to imported from the main.
But this is the actual error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/alex/portal/main.py", line 15, in <module>
db = SQLAlchemy(app)
File "/home/alex/portal/venv/lib/python3.10/site-packages/flask_sqlalchemy/extension.py", line 219, in __init__
self.init_app(app)
File "/home/alex/portal/venv/lib/python3.10/site-packages/flask_sqlalchemy/extension.py", line 326, in init_app
engines[key] = self._make_engine(key, options, app)
File "/home/alex/portal/venv/lib/python3.10/site-packages/flask_sqlalchemy/extension.py", line 614, in _make_engine
return sa.engine_from_config(options, prefix="")
File "/home/alex/portal/venv/lib/python3.10/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/alex/portal/venv/lib/python3.10/site-packages/sqlalchemy/util/deprecations.py", line 277, in warned
return fn(*args, **kwargs) # type: ignore[no-any-return]
File "/home/alex/portal/venv/lib/python3.10/site-packages/sqlalchemy/engine/create.py", line 556, in create_engine
entrypoint = u._get_entrypoint()
File "/home/alex/portal/venv/lib/python3.10/site-packages/sqlalchemy/engine/url.py", line 754, in _get_entrypoint
cls = registry.load(name)
File "/home/alex/portal/venv/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py", line 365, in load
raise exc.NoSuchModuleError(
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:sqllite
If you have any suggestions please let me know.
Plus I am trying to put this code in the "_ init _.py" from the script in order to have a cleaner code.
You have mis-spelled sqlite as sqllite:
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///databse.db'
But even if you fix that you're going to have additional problems, because you're redefining app at the end of your code. Here's a working example, which is a simplified version of this example from the documentation.
from flask import Flask, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///databse.db"
app.config["SECRET_KEY"] = "ca8b6694c31960d1f7ee2d1ac73c669f"
db = SQLAlchemy(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)
def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
with app.app_context():
db.create_all()
#app.route("/users", methods=["GET"])
def user_list():
res = db.session.execute(db.select(User).order_by(User.username)).scalars()
users = res.fetchall()
return [user.as_dict() for user in users]
#app.route("/users", methods=["POST"])
def user_create():
user = User(**request.get_json())
db.session.add(user)
db.session.commit()
return user.as_dict()
#app.route("/user/<int:id>")
def user_detail(id):
user = db.get_or_404(User, id)
return user.as_dict()
You can create a user entry:
$ curl http://localhost:5000/users -H content-type:application/json \
-d '{"username": "alice", "email": "alice#example.com"}'
{
"email": "alice#example.com",
"id": 1,
"username": "alice"
}
Get a list of users:
$ curl http://localhost:5000/users
[
{
"email": "alice#example.com",
"id": 1,
"username": "alice"
}
]
Get details on a single user:
$ curl http://localhost:5000/user/1
{
"email": "alice#example.com",
"id": 1,
"username": "alice"
}
Etc.
Related
I've tried this before and it worked, now I'm doing it again but it doesn't. I use a virtual env.
The db file is in the same directory as the init and models. I've also executed the db.create_all() in the python shell after importing db. The error occurs when I execute Students.query.all(). I'm really confused now. I compared my codes with my existing projects and it is the same. I don't understand why it doesn't work.
Traceback (most recent call last):
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1246, in _execute_context
cursor, statement, parameters, context
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\default.py", line 581, in do_execute
cursor.execute(statement, parameters)
sqlite3.OperationalError: no such table: students
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\orm\query.py", line 3211, in all
return list(self)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\orm\query.py", line 3367, in __iter__
return self._execute_and_instances(context)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\orm\query.py", line 3392, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 982, in execute
return meth(self, multiparams, params)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\sql\elements.py", line 287, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1101, in _execute_clauseelement
distilled_params,
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1250, in _execute_context
e, statement, parameters, cursor, context
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1476, in _handle_dbapi_exception
util.raise_from_cause(sqlalchemy_exception, exc_info)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\util\compat.py", line 398, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\util\compat.py", line 152, in reraise
raise value.with_traceback(tb)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1246, in _execute_context
cursor, statement, parameters, context
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\default.py", line 581, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: students
[SQL: SELECT students.id AS students_id, students.last_name AS students_last_name, students.college AS students_college, students.email AS students_email
FROM students]
(Background on this error at: http://sqlalche.me/e/e3q8)
_ _ init _ _.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
main = Flask(__name__)
main.config['SECRET_KEY'] = '3bce79429ad6b79670e4e800fb4a57b9'
main.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(main)
from reg import routes
models.py:
from reg import db
class Students(db.Model):
id = db.Column(db.Integer, primary_key=True)
last_name = db.Column(db.String(60), nullable=False)
college = db.Column(db.String(60), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"Student('{self.last_name}','{self.college}','{self.email}')"
It probably has to do with where you are calling db.create_all(). You have to call it after you have defined all of your models. Here is a working example in one module:
import flask
from flask_sqlalchemy import SQLAlchemy
app = flask.Flask(__name__)
app.config['SECRET_KEY'] = '3bce79429ad6b79670e4e800fb4a57b9'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
class Students(db.Model):
id = db.Column(db.Integer, primary_key=True)
last_name = db.Column(db.String(60), nullable=False)
college = db.Column(db.String(60), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"Student('{self.last_name}','{self.college}','{self.email}')"
db.create_all()
#app.route("/students", methods=["GET"])
def all_students():
students = Students.query.all()
resp = []
for student in students:
resp.append(dict(
id=student.id,
last_name=student.last_name,
college=student.college,
email=student.email
))
return flask.jsonify(resp), 200
#app.route("/students/<_id>", methods=["GET"])
def student_by_id(_id):
student = Students.query.get(_id)
if student:
resp = dict(
id=student.id,
last_name=student.last_name,
college=student.college,
email=student.email
)
return flask.jsonify(resp), 200
else:
return "", 404
#app.route("/students", methods=["POST"])
def add_student():
req = flask.request.get_json()
student = Students(**req)
db.session.add(student)
db.session.commit()
resp = flask.make_response()
resp.headers["Location"] = flask.url_for("student_by_id", _id=student.id)
return resp, 201
In your example I did not see a call to db.create_all() but I suspect that it is in the wrong spot. Using your example, I believe it will work if you move the call from where you have it to the end of your __init__.py:
__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
main = Flask(__name__)
main.config['SECRET_KEY'] = '3bce79429ad6b79670e4e800fb4a57b9'
main.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(main)
from reg import routes
db.create_all()
In the shell, import the database and the models first before executing db.create_all(). Apparently, error occurs when create you create database without importing the models.
My mistake was:
>>from APPFOLDER import db
>>db.create_all()
>>from APPFOLDER.models import MODELNAME
>>MODELNAME.query.all()
***ERROR MSG***
What you should do:
>>from APPFOLDER import db
>>from APPFOLDER.models import MODELNAME
>>db.create_all()
>>MODELNAME.query.all()
[]
I have written my unitest in flask like (with in memory database);
import unittest
import json
from lobdcapi import app
from dal.dbContext import db
from models.AtgSiteToPoll import *
class TestAtgSiteToPollEP(unittest.TestCase):
def setUp(self):
app.testing = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
self.app = app.test_client()
with app.app_context():
db.init_app(app)
db.drop_all()
db.create_all()
def tearDown(self):
pass
def test_atg_sitetopoll(self):
a = AtgSiteToPoll()
a.SiteId = 1
a.IPAddress = '10.10.10.10'
a.Port = 3000
a.Category = 1
a.UserId = 'test'
a.Password = 'test123'
a.ReceiveTimeoutInMilliSeconds = 60
db.session.add(a)
db.session.commit()
assert len(AtgSiteToPoll.query.all()) is 1
When running the test I get;
Traceback (most recent call last):
File "/Users/ratha/projects/test711/ATGWS/tests/TestAtgSitesToPollEP.py", line 31, in test_atg_sitetopoll
db.session.add(a)
File "/Users/ratha/projects/test711/ATGWS/venv/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py", line 153, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/Users/ratha/projects/test711/ATGWS/venv/lib/python2.7/site-packages/sqlalchemy/util/_collections.py", line 1001, in __call__
return self.registry.setdefault(key, self.createfunc())
File "/Users/ratha/projects/test711/ATGWS/venv/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2939, in __call__
return self.class_(**local_kw)
File "/Users/ratha/projects/test711/ATGWS/venv/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 141, in __init__
self.app = app = db.get_app()
File "/Users/ratha/projects/test711/ATGWS/venv/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 912, in get_app
'No application found. Either work inside a view function or push'
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
What Im doing wrong here?
I'm following the official sqlalchemy tutorial on getting started, yet when I try to instantiate the User class below, I'm told by the interpreter that it's not callable. I have no idea why. Anyone have any idea?
__init__.py
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
user.py
from sqlalchemy import Column, Integer, String
from __init__ import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)
user_api.py
from flask import request
from flask.views import MethodView
from src.main.model.user import User
class UserAPI(MethodView):
def post(self):
usr = User(**request.form)
return usr
__main__.py
import flask
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from src.main.endpoints.user_api import UserAPI
from src.main.model import Base
def database_stuff():
engine = create_engine('sqlite:///:memory:', echo=True)
Session = sessionmaker(bind=engine)
Base.metadata.create_all(engine)
if __name__ == "__main__":
database_stuff()
app = flask.Flask(__name__)
user_view = UserAPI.as_view("users")
app.add_url_rule("/users/", defaults={"user_id": None}, view_func=user_view, methods=["GET"])
app.add_url_rule("/users/", view_func=user_view, methods=["POST"])
app.add_url_rule("/users/<int:user_id>", view_func=user_view, methods=["GET"])
app.run()
When attempting to do a post request to the Flask server, this is what I'm getting in the logs:
Traceback (most recent call last):
File "D:\Documents\python\flaskplay\flaskplay\lib\site-packages\flask\app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "D:\Documents\python\flaskplay\flaskplay\lib\site-packages\flask\app.py", line 1615, in full_dispatch_request
return self.finalize_request(rv)
File "D:\Documents\python\flaskplay\flaskplay\lib\site-packages\flask\app.py", line 1630, in finalize_request
response = self.make_response(rv)
File "D:\Documents\python\flaskplay\flaskplay\lib\site-packages\flask\app.py", line 1740, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "D:\Documents\python\flaskplay\flaskplay\lib\site-packages\werkzeug\wrappers.py", line 885, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "D:\Documents\python\flaskplay\flaskplay\lib\site-packages\werkzeug\wrappers.py", line 57, in _run_wsgi_app
return _run_wsgi_app(*args)
File "D:\Documents\python\flaskplay\flaskplay\lib\site-packages\werkzeug\test.py", line 884, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: 'User' object is not callable
127.0.0.1 - - [05/Jun/2017 20:44:32] "POST /users/ HTTP/1.1" 500 -
It actually has nothing to do with sqlalchemy. The object is indeed callable and instantiable. The error actually comes with attempting to return the object as a response. You can't just return any old object from a Flask endpoint. If I convert the object dict to json, then the error is no longer applicable.
I'm learning to create API's using Python here. I've gotten everything ready and downloaded the database, however when I run my app I'm getting the following error:
Traceback (most recent call last):
File "app.py", line 7, in <module>
e = create_engine("sqlite3:///salaries.db")
File "C:\Python27\lib\site-packages\sqlalchemy\engine\__init__.py", line 387, in create_engine
return strategy.create(*args, **kwargs)
File "C:\Python27\lib\site-packages\sqlalchemy\engine\strategies.py", line 56, in create
entrypoint = u._get_entrypoint()
File "C:\Python27\lib\site-packages\sqlalchemy\engine\url.py", line 139, in _get_entrypoint
cls = registry.load(name)
File "C:\Python27\lib\site-packages\sqlalchemy\util\langhelpers.py", line 212, in load
(self.group, name))
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:sqlite3
What am I doing wrong to where it will not load the correct plugin?
from flask import Flask, request
from flask_restful import Resource, Api
from sqlalchemy import create_engine
from json import dumps
e = create_engine("sqlite3:///salaries.db")
app = Flask(__name__)
api = Api(app)
class DepartmentsMeta(Resource):
def get(self):
conn = e.connect()
query = conn.execute("select distinct DEPARTMENT from salaries")
return {"departments": [i[0] for i in query.cursor.fetchall()]}
class DepartmentSalary(Resource):
def get(self, department_name):
conn = e.connect()
query = conn.execute("select * from salaries where Department='%s'" % department_name)
result = {"data": [dict(zip(tuple(query.keys()), i))] for i in query.cursor}
return result
api.add_resource(DepartmentSalary, "/dept/<string:department_name>")
api.add_resource(DepartmentsMeta, "/department")
if __name__ == "__main__":
app.run()
Please try replacing this line:
e = create_engine("sqlite3:///salaries.db")
with
e = create_engine("sqlite:///salaries.db")
I got the same problem. I've solved it by:
pip3 uninstall flask_sqlalchemy and pip3 install flask-sqlalchemy==2.5.1 because big changes with flask-sqlalchemy==3.0 SQLite DB in memory are not set as default in this version.
Hope it helps you.
Database example.db is created but generates error !!!
Traceback (most recent call last):
File "db_testing.py", line 39, in admin.save()
File "C:\Users\dell\Envs\surveyApp\lib\site-packages\peewee.py", line 2405, in save
new_pk = insert.execute()
File "C:\Users\dell\Envs\surveyApp\lib\site-packages\peewee.py", line 1721, in execute
return self.database.last_insert_id(self._execute(), self.model_class)
File "C:\Users\dell\Envs\surveyApp\lib\site-packages\peewee.py", line 1420, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File "C:\Users\dell\Envs\surveyApp\lib\site-packages\peewee.py", line 1824, in execute_sql
res = cursor.execute(sql, params or ())
sqlite3.IntegrityError: column email is not unique
Code
import datetime
from flask import Flask
from flask_peewee.admin import Admin
from flask_peewee.auth import Auth
from flask_peewee.db import Database
from peewee import *
# configure our database
DATABASE = {
'name': 'example.db',
'engine': 'peewee.SqliteDatabase',
}
DEBUG = True
SECRET_KEY = 'ssshhhh'
app = Flask(__name__)
app.config.from_object(__name__)
# instantiate the db wrapper
db = Database(app)
# create an Auth object for use with our flask app and database wrapper
auth = Auth(app, db)
admin = Admin(app, auth)
class Note(db.Model):
message = TextField()
created = DateTimeField(default=datetime.datetime.now)
admin.register(Note)
admin.setup()
if __name__ == '__main__':
auth.User.create_table(fail_silently=True)
Note.create_table(fail_silently=True)
admin = auth.User(username='admin', email='aoeu#gmail.com', admin=True, active=True)
admin.set_password('admin')
admin.save()
app.run()
using example from
http://flask-peewee.readthedocs.org/en/latest/getting-started.html#setting-up-a-simple-base-template
Database was already created, deleting previous database solved it