This is what I have in my app.py:
from flask import Flask, render_template, url_for, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///D:/Documents/.my projects/flask-website/blog.db'
db = SQLAlchemy(app)
class Blogpost(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50))
subtitle = db.Column(db.String(50))
author = db.Column(db.String(20))
date_posted = db.Column(db.DateTime)
content = db.Column(db.Text)
if __name__ == '__main__':
app.run(debug=True)
and in python terminal, I try this:
>>> from app import db
>>> db.create_all()
Then I check to see if the table has been created using command prompt:
> sqlite3 blog.db
> .tables
Nothing gets returned, which I believe means that no tables are in the database. I'm following the tutorial here, but maybe the tutorial is out of date, so I'm not really sure where to go from here.
I am using python 3.9
Turns out I had my file path wrong in app.config['SQLALCHEMY_DATABASE_URI']... currently hitting my head on my desk because I have spent more time than I care to admit on this issue.
Related
I am beyond confused at this point. I have read so much documentation and there seems to be sparse examples of what to do for running raw SQL statements on my flask app using Flask_sqlalchemy or flask_mysqldb.
I have started by downloading XAMPP and creating a database on MySQL server through my localhost. I then created my flask application and created an initial database from the terminal using
>>> from yourapplication import db
>>> db.create_all()
The code from my flask app is as follows based on the documentation here
from flask import Flask, render_template, request, redirect, session
from flask_session import Session
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from werkzeug.security import check_password_hash, generate_password_hash
# Set up Flask instance
app = Flask(__name__)
# Configure db
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root#localhost/hoook"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
# Reload templates when changed (take down when in production)
app.config["TEMPLATES_AUTO_RELOAD"] = True
# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Create db model
class Users(db.Model):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.Text, nullable=False)
last_name = db.Column(db.Text, nullable=False)
email = db.Column(db.Text, unique=True, nullable=False)
password = db.Column(db.Text, nullable=False)
date = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return "<Users %r>" % self.id
great, now I can see my table in myPhpAdmin. I then ran a test statement to see if information would be added as follows
db.engine.execute("INSERT INTO users (first_name, last_name, email, password) VALUES ('chris', 'blah', 'blah#gmail.com', 'something')")
works! but then looking at the previous stackoverflow answer and then the subsequent documentation I find this method is depreciated therefore I cant use this going forward. So I try to use session.execute instead (since connection.execute also shows its depreciated) as I see that for some reason there are three different methods all with the same function execute() that can be used...???? source. So using the following statement I try to add another row to my table but it failed.
db.session.execute("INSERT INTO users (first_name, last_name, email, password) VALUES ('jeremy', 'blah', 'something#gmail.com', 'whatever')")
there were no error messages, just when I check my database, nothing new was added. So if I got this right engine.execute didnt need a connection but session does? Does that mean this line
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root#localhost/hoook"
is actually not connecting the session method to my database then? What about the pymysql connector in the URI? do I also need to import pymysql to be able to use this connector? What is the correct method for generating queries and being able to add tables etc from within your flask app... Please clarify as this is confusing and from my point of view, all this documentation and abstraction needs to be cleaned up.
i'm beginner with flask-sqlalchemy.
i encountered a problem maybe caused by using backref.
the api(view api. it renders template) is like this.
#board.route('/')
def index():
page = request.args.get('page', 1, type=int)
q = Article.query.order_by(Article.create_date.desc())
article_list_pagination = q.paginate(page, per_page=10)
return render_template('board.html', article_list=article_list_pagination)
and the model is like this
class Answer(db.Model):
__tablename__ = 'answer'
id = db.Column(db.Integer, primary_key=True)
article_id = db.Column(db.Integer, db.ForeignKey('article.id', ondelete='CASCADE'))
article = db.relationship('Article', backref=db.backref('answer_set'))
user_id = db.Column(db.String(255), nullable=False)
name = db.Column(db.String(255), nullable=False)
content = db.Column(db.Text(), nullable=False)
create_date = db.Column(db.DateTime(), nullable=False)
update_date = db.Column(db.DateTime(), nullable=True)
when i request the api every 20 times, i get this error
sqlalchemy.exc.TimeoutError: QueuePool limit of size 10 overflow 10 reached, connection timed out, timeout 30.00 (Background on this error at: https://sqlalche.me/e/14/3o7r)
here is what i tried to solve the error.
give lazy options to db.relationship. but doesn't work
db.session.close(). but it makes another error
sqlalchemy.orm.exc.DetachedInstanceError: Parent instance <Article at 0x1772756baf0> is not bound to a Session; lazy load operation of attribute 'answer_set' cannot proceed
debug=False. it doesn't work, too.
how can i get over this problem?
+++
when I remove
article = db.relationship('Article', backref=db.backref('answer_set')) from the model and
add db.session.close() before return template,
it doesn't make error, but i need it.
what should i do?
+++++ answers for comment #branco
i'm just using flask-sqlalchemy paginate method.
https://flask-sqlalchemy.palletsprojects.com/en/2.x/api/
and i'm running this app at app.py
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import JWTManager
import config
db = SQLAlchemy()
migrate = Migrate()
def create_app():
app = Flask(__name__)
app.secret_key = 'secret_key_for_flash'
app.config.from_object(config)
db.init_app(app)
migrate.init_app(app, db)
from models.user import User
from models.article import Article
from models.answer import Answer
from blueprints.main import main
from blueprints.login import login
from blueprints.register import register
from blueprints.board.board import board
from blueprints.board.article import article
from blueprints.board.answer import answer
app.register_blueprint(main)
app.register_blueprint(login)
app.register_blueprint(register)
app.register_blueprint(board)
app.register_blueprint(article)
app.register_blueprint(answer)
app.config['JWT_SECRET_KEY'] = 'jwt_secret_key'
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = config.expires_access
app.config['JWT_REFRESH_TOKEN_EXPIRES'] = config.expires_refresh
app.config['JWT_TOKEN_LOCATION'] = ['cookies']
JWTManager(app)
return app
if __name__ == '__main__' :
create_app().run(debug=True)
finally, i solved this problem. i just gave lazy options to db.relationship. but didn't work. i had to give lazy option to db.backref. like
article = db.relationship('Article', backref=db.backref('answer_set', lazy='joined'))
and added
db.session.close()
after i called paginate method
I'm trying to run an SQLAlchemy query on my Flask web app (hosted on PythonAnywhere) and I'm stuck - I'm new to SQLAlchemy and have tried to search around for the answer and tried a few different solutions but nothing worked.
This is the initial set up:
from flask import Flask, redirect, render_template, request, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_login import login_required, login_user, LoginManager, logout_user, UserMixin, current_user
from werkzeug.security import check_password_hash, generate_password_hash
import requests
import urllib.parse
app = Flask(__name__)
app.config["DEBUG"] = True
SQLALCHEMY_DATABASE_URI = "mysql+mysqlconnector://{username}:{password}#{hostname}/{databasename}".format(
username="****",
password="****",
hostname="****",
databasename="****",
)
app.config["SQLALCHEMY_DATABASE_URI"] = SQLALCHEMY_DATABASE_URI
app.config["SQLALCHEMY_POOL_RECYCLE"] = 299
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
app.secret_key = "58f5x^G!S8q8p6MZDRHa"
login_manager = LoginManager()
login_manager.init_app(app)
[...]
class Portfolio(db.Model):
__tablename__ = "portfolio"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
symbol = db.Column(db.String(32))
quantity = db.Column(db.Integer)
user = db.Column(db.String(32))
And query I am trying to run - the first section works, in the second section I am trying to filter the table by the symbol given in the form (I have put it 'NFLX' just to see if the query itself would work) to check if that entry already exists - with the intention to then have different behaviours based on whether curr_portfolio is none/null.
# add transaction to Transaction database
transaction = Transaction(symbol=request.form["symbol"], quantity=request.form["shares"], totalvalue=cost, user="admin")
db.session.merge(transaction)
db.session.commit()
# add transaction to Portfolio database
symbol=(request.form.get("symbol")
curr_portfolio = session.query(Portfolio.symbol).filter(symbol="NFLX").all()
return redirect(url_for('dashboard'))
Any pointers greatly appreciated!
Use db.session.query(Portfolio.symbol).filter(Portfolio.symbol == symbol).all()
Or Portfolio.query.filter(Portfolio.symbol == symbol).all()
Use:
curr_portfolio = session.query(Portfolio.symbol).filter_by(symbol="NFLX").all()
or
curr_portfolio = session.query(Portfolio.symbol).filter(Portfolio.symbol=="NFLX").all()
I've looked at the other posts with this same title, but they did not fix my problem. The error message in the above title is what I am getting.
I've made a simple database and constructor for the database. Just to test, I'm trying to add the word "hello" to the column "words" in the class User. But I keep getting this error. I've already tried putting autoincrement in the class column, but I ended it up getting another error. What is going wrong? Please see the code below. Python and Flask.
from flask import Flask, request, redirect, url_for, render_template
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
import sqlite3
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE URI"] = 'sqlite:///test.db'
db = SQLAlchemy(app)
class User(db.Model):
__tablename__ = 'user'
words = db.Column(db.String(200), primary_key=True)
def __init__(self, thewords):
self.thewords = thewords
db.create_all()
db.session.commit()
texts = "hello"
textstuffent = User(texts)
db.session.add(textstuffent)
db.session.commit()
results = User.query.all()
print(results)
#app.route('/', methods = ['POST', 'GET'])
def hello():
return render_template('Textarea.html')
app.run(debug=True)
For anyone who visits this page in the future, I've found what was wrong. I did not reference "words" as "self.words". My code now works and I am relieved to finally continue coding so that some other bug can confound me later down the road. Please see below. You can see the difference in code in the User class. I used query.all() to prove that data has made it into the database.
from flask import Flask, request, redirect, url_for, render_template
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
import sqlite3
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE URI"] = 'sqlite:///test.db'
db = SQLAlchemy(app)
class User(db.Model):
words = db.Column(db.String(200), primary_key=True, nullable=False)
def __init__(self, thewords):
self.words = thewords
db.create_all()
db.session.commit()
texts = "hello"
textstuffent = User(texts)
db.session.add(textstuffent)
db.session.commit()
print(User.query.all())
#app.route('/', methods = ['POST', 'GET'])
def hello():
return render_template('Textarea.html')
app.run(debug=True)
I've searched for this answer for the past day and a half and I think my issue has something to do with my Pycharm Settings. When I run the code below I don't get any errors but the database file never gets created. I'm trying to recreate the app following this tutorial: https://www.youtube.com/watch?v=2geC50roans
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE__URI'] = 'sqlite:///pin.db'
db = SQLAlchemy(app)
class Pin(db.Model):
id = db.Column(db.Integer, primary_key=True)`enter code here`
title = db.Column(db.Text, unique=False)
image = db.Column(db.Text, unique=False)
db.create_all()
#app.route('/')
def hello_world():
return 'Hello World!'
app.debug = True
if __name__ == '__main__':
app.run()
enter code here
This code does not create the database as mentioned in the link you provided:
To create the initial database, just import the db object from an interactive Python shell and run the SQLAlchemy.create_all() method to create the tables and database:...
To create the db programatically, use create_engine:
engine = create_engine('sqlite:///mydirectory/myfile.db, convert_unicode=True)
session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base.query = session.query_property()
More info:
http://flask.pocoo.org/docs/0.10/patterns/sqlalchemy/