Flask: sqlalchemy.exc.OperationalError - python

So, I'm trying to create a blog that has users who can create posts, within any post there should be comments written by the users.
That's my code:
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), nullable=False, unique=True)
email = db.Column(db.String(120), nullable=False, unique=True)
password = db.Column(db.String(60), nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
posts = db.relationship('Post', backref='author', lazy=True)
comments = db.relationship('Comment', backref='commentauthor', lazy=True)
def __repr__(self):
return f"User('{self.username}','{self.email}','{self.image_file}')"
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
comments = db.relationship('Comment', backref='postcontainer', lazy=True)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
class Comment(db.Model):
id = db.Column(db.Integer, primary_key=True)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def __repr__(self):
return f"Comment('{self.content}', '{self.date_posted}')"
Also the code at my route:
#app.route("/", methods=['POST', 'GET'])
def home():
page = request.args.get('page', 1, type=int)
posts = Post.query.order_by(Post.date_posted.desc()).paginate(page=page, per_page=5)
cpost = CreatePost()
if cpost.validate_on_submit():
post = Post(title=cpost.title.data, content=cpost.content.data, author=current_user)
db.session.add(post)
db.session.commit()
return redirect(url_for('home'))
ccomment = CreateComment()
comments = Comment.query.all()
if ccomment.validate_on_submit():
comment = Comment(content=ccomment.content.data)
db.session.add(comment)
db.session.commit()
return redirect(url_for('home'))
return render_template('home.html', posts=posts, cpost=cpost, ccomment=ccomment, comments=comments)
I end up getting this error:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such
table: comment [SQL: SELECT comment.id AS comment_id,
comment.date_posted AS comment_date_posted, comment.content AS
comment_content, comment.post_id AS comment_post_id, comment.user_id
AS comment_user_id FROM comment] (Background on this error at:
http://sqlalche.me/e/e3q8)
Traceback (most recent call last)
How can I fix this?

You need to create the comment table in your database, if you are using flask-sqlalchemy extension then you only need to call this function https://flask-sqlalchemy.palletsprojects.com/en/2.x/api/#flask_sqlalchemy.SQLAlchemy.create_all
https://flask-sqlalchemy.palletsprojects.com/en/2.x/quickstart/

Go to your python shell window and type:
from name import db
db.create_all()
name is the name of your project.

Related

How to get rid of this error sqlalchemy.exc.ArgumentError

Hello i would like to know how to get rid of this error. Here are my my tables
#login_menager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(60),nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
user_comments = db.relationship('Comment', backref='author_comment', lazy=True)
def __repr__(self):
return f"User('{self.username}', '{self.email}')"
class Comment(db.Model):
id = db.Column(db.Integer, primary_key = True)
body = db.Column(db.Text)
timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
#post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)
comment_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def __repr__(self):
return f"Comment('{self.body}')"
When i add these lines:
if comment_form.validate_on_submit():
reply = Comment(body=comment_form.comment_on_form.data, author_comment=current_user)
db.session.add(reply)
db.session.commit()
replies = Comment.query.filter_by(author_comment=current_user).order_by(Comment.timestamp.desc()).all()
return render_template('home.html', posts=posts, title='Home', form=form, comment_form=comment_form, replies=replies)
I get this error:
sqlalchemy.exc.ArgumentError: Mapped instance expected
for relationship comparison to object.
Classes, queries and other SQL elements are not accepted in this context;
for comparison with a subquery, use Comment.author_comment.has(**criteria).
With trackback:
https://raw.githubusercontent.com/RealdoBeja98/endi-s_project/main/README.md
I would appreciate any help. Thank you

I am getting "AttributeError: 'int' object has no attribute 'filter'

I want this to be able to filter post by the CURRENT USER and delete it. Someone told me to use .WHERE instead of .FILTER but neither of them are working and I get an Attribute Error. How can I get this working?
By the way I am able to delete ALL user post with just db.session.query(Post).delete() but I want it so it only deletes posts for CURRENT_USER.ID (the user that is currently logged into my session)
I added my current models:
#login_required
def delete_all_post():
if current_user.is_authenticated:
db.session.query(Post).delete().filter(Post.user_id == current_user.id)
db.session.commit()
flash('All of your posts has been deleted!', 'success')
return redirect(url_for('main.home'))```
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def __repr__(self):
return f"Post('{self.title}', {self.date_posted}')"
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(16), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
delete() return True/ False which is 0 or 1 which is int so you cannot do filter over it
try:
db.session.query(Post).filter(Post.user_id == current_user.id).delete()

How to display list of users who have liked a post in Flask app?

I am new to Flask and I have created a social media blog using Flask by following videos of Corey Schafer and Miguel Grinberg, I have incorporated additional functionalities such as Liking a post and Commenting on a post. All of the functionalities that I have incorporated are functioning properly but I cannot view the users who have liked a post.
here is my routes.py file that has the like and ViewLikers route
#app.route('/like/<int:post_id>/<action>')
#login_required
def like_action(post_id, action):
post = Post.query.filter_by(id=post_id).first_or_404()
if action == 'like':
current_user.like_post(post)
db.session.commit()
if action == 'unlike':
current_user.unlike_post(post)
db.session.commit()
return redirect(request.referrer)
#app.route('/like/<int:post_id>/viewLikes')
#login_required
def viewLikers(post_id):
post = Post.query.get_or_404(post_id)
return render_template('viewLikes.html', likers=post.get_likers())
Here is my models.py file
class PostLike(db.Model):
__tablename__ = 'PostLike'
id = db.Column(db.Integer, primary_key=True)
users_id = db.Column(db.Integer, db.ForeignKey('user.id'))
post_id = db.Column(db.Integer, db.ForeignKey('post.id'))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
followed = db.relationship(
'User', secondary=followers,
primaryjoin=(followers.c.follower_id == id),
secondaryjoin=(followers.c.followed_id == id),
backref=db.backref('followers', lazy='dynamic'), lazy='dynamic')
liked = db.relationship(
'PostLike',
foreign_keys='PostLike.users_id',
backref='user', lazy='dynamic')
def like_post(self, post):
if not self.has_liked_post(post):
like = PostLike(users_id=self.id, post_id=post.id)
db.session.add(like)
def unlike_post(self, post):
if self.has_liked_post(post):
PostLike.query.filter_by(
users_id=self.id,
post_id=post.id).delete()
def has_liked_post(self, post):
return PostLike.query.filter(
PostLike.users_id == self.id,
PostLike.post_id == post.id).count() > 0
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), unique=True, nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
likes = db.relationship('PostLike', backref='post', lazy='dynamic')
comments = db.relationship('Comment', backref='title', lazy='dynamic')
def get_likers(self):
return PostLike.query.filter_by(users_id =User.id, post_id=self.id)
But when I click on the viewLikes button in the template it gives me an error stating Function doesn't return any view
Simple error. In the last method you haven't returned the render_template. return render_template('')
Also call .first() on your post object

Flask Application - view posts of current user only

Beginner programmer here. Trying to create a flask app which users can post into. I am looking to create a "home page" where users can see their posts rather than every users posts.
Here is my code:
routes.py
#app.route("/home")
def home():
posts = Post.query.all()
return render_template('home.hmtl', posts=posts)
models.py
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.image_file}')"
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
Any help would be greatly appreciated!
First of all get, get the current user using session or jwt's.
Then you can now query your database to get posts by the current user only.
You can use current_user case
#app.route("/home", methods=['GET', 'POST'])
def home():
posts = current_user.posts
return render_template('home.html', posts=posts)

AttributeError: 'int' object has no attribute '_sa_instance_state'

I'm working on forum template using Flask. When I attempt creating a new thread in the browser using forms, SQLAlchemy throws an AttributeError. The problem showed up when I tried implementing a one-to-many relationship with Forum-to-Thread and a one-to-many relationship with Thread-to-User.
models.py
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(32), index=True, unique=True)
password = db.Column(db.String(32), index=True)
email = db.Column(db.String(120), index=True, unique=True)
role = db.Column(db.SmallInteger, default=ROLE_USER)
posts = db.relationship('Post', backref='author', lazy='dynamic')
class Forum(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(128))
description = db.Column(db.Text)
threads = db.relationship('Thread', backref='forum', lazy='dynamic')
class Thread(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(128))
author= db.Column(db.String(32))
timestamp = db.Column(db.DateTime)
forum_id = db.Column(db.Integer, db.ForeignKey('forum.id'))
posts = db.relationship('Post', backref='thread', lazy='dynamic')
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.Text)
timestamp = db.Column(db.DateTime)
thread_id = db.Column(db.Integer, db.ForeignKey('thread.id'))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
All the new posts/threads and handled within views.py
views.py
#app.route('/forum/id=<id>/submit', methods=['GET','POST'])
#login_required
def new_thread(id):
form = ThreadForm()
forum = Forum.query.filter_by(id=id).first()
if form.validate_on_submit():
thread = Thread(title=form.title.data,
author=g.user.username,
timestamp=datetime.utcnow())
db.session.add(thread)
db.session.flush()
post = Post(body=form.body.data,
timestamp=datetime.utcnow(),
thread=thread.id,
author=g.user.id)
db.session.add(post)
db.session.commit()
flash('Post successful.')
return redirect(url_for('forum_index', id=id))
return render_template('forum/thread_submit.html', title=forum.title, form=form)
the problem is this:
post = Post(body=form.body.data,
timestamp=datetime.utcnow(),
thread=thread.id,
author=g.user.id)
you want to work with ORM objects, not primary key columns:
post = Post(body=form.body.data,
timestamp=datetime.utcnow(),
thread=thread,
author=g.user)
the error means that an integer is being interpreted as an ORM object.

Categories