Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Y B
Y B
14,136 Points

Flask social app - peewee Textfield error

I'm part way through the flask social app course (just finished broadcasting section) and I noticed that the posts were not outputting correctly. I had an error where I had forgotten to put the brackets after the Textfield in the post model for the content attribute.

Putting these in breaks everything and I get a peewee operational error: no such column: t1.content

This looks to be an error associated with the post view function. Perhaps with form.content.data.strip() but I double checked compared to the course and I look to have typed it correctly.

Any idea what I might be doing incorrectly? (i've posted the app, models and forms files below).

Thanks

from flask import (Flask, g, render_template, flash, redirect, url_for)
from flask.ext.bcrypt import check_password_hash
from flask.ext.login import (LoginManager, login_user, logout_user,
                             login_required, current_user)

import forms
import models

DEBUG = True
PORT = 8000
HOST = '0.0.0.0'

app = Flask(__name__)
app.secret_key = 'asdfsadfasjowherhdkf13498)*&4kj>M>SMIUO@jaso83j>.'

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'


@login_manager.user_loader
def load_user(userid):
    try:
        return models.User.get(models.User.id == userid)
    except models.DoesNotExist:
        return None


@app.before_request
def before_request():
    """Connect to the database before each request"""
    g.db = models.DATABASE
    g.db.connect()
    g.user = current_user


@app.after_request
def after_request(response):
    """Close the database connection after each request"""
    g.db.close()
    return response


@app.route('/register', methods=('GET', 'POST'))
def register():
    form = forms.RegisterForm()
    if form.validate_on_submit():
        flash('You have registered', "success")
        models.User.create_user(
            username=form.username.data,
            email=form.email.data,
            password=form.password.data
        )
        return redirect(url_for('index'))
    return render_template('register.html', form=form)


@app.route('/login', methods=('GET', 'POST'))
def login():
    form = forms.LoginForm()
    if form.validate_on_submit():
        try:
            user = models.User.get(models.User.email == form.email.data)
        except models.DoesNotExist:
            flash("Your email or password doesn't match", 'error')
        else:
            if check_password_hash(user.password, form.password.data):
                login_user(user)
                flash("You've been logged in!", "success")
                return redirect(url_for('index'))
            else:
                flash("Your email or password doesn't match!", "error")
    return render_template('login.html', form=form)


@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash("You've been logged out!", "success")
    return redirect(url_for('index'))


@app.route('/new_post', methods=('GET', 'POST'))
@login_required
def post():
    form = forms.PostForm()
    if form.validate_on_submit():
        models.Post.create(user=g.user._get_current_object(),
                           content=form.content.data.strip())
        flash("Message posted! Thanks!", "success")
        return redirect(url_for('index'))
    return render_template('post.html', form=form)


@app.route('/')
def index():
    stream = models.Post.select().limit(100)
    return render_template('stream.html', stream=stream)


@app.route('/stream')
@app.route('/stream/<username>')
def stream(username=None):
    template = 'stream.html'
    if username and username != current_user.username:
        user = models.User.select().where(models.User.username**username).get()
        stream = user.posts.limit(100)
    else:
        stream = current_user.get_stream().limit(100)
        user = current_user
    if username:
        template = 'user_stream.html'
    return render_template(template, stream=stream, user=user)


if __name__ == '__main__':
    models.initialize()
    try:
        models.User.create_user(
            username='BG',
            email='b@gmail.com',
            password='12345',
            admin=True
        )
    except ValueError:
        pass
    app.run(debug=DEBUG, host=HOST, port=PORT)
import datetime

from flask.ext.login import UserMixin
from flask.ext.bcrypt import generate_password_hash
from peewee import *

DATABASE = SqliteDatabase('social.db')


class User(UserMixin, Model):
    username = CharField(unique=True)
    email = CharField(unique=True)
    password = CharField(max_length=100)
    joined_at = DateTimeField(default=datetime.datetime.now)
    is_admin = BooleanField(default=False)

    class Meta:
        database = DATABASE
        order_by = ('-joined_at',)

    def get_posts(self):
        return Post.select().where(Post.user == self)

    def get_stream(self):
        return Post.select().where(
            (Post.user == self)
        )

    @classmethod
    def create_user(cls, username, email, password, admin=False):
        try:
            with DATABASE.transaction():
                cls.create(
                    username=username,
                    email=email,
                    password=generate_password_hash(password),
                    is_admin=admin)
        except IntegrityError:
            raise ValueError("User already exists")


class Post(Model):
    timestamp = DateTimeField(default=datetime.datetime.now)
    user = ForeignKeyField(
        rel_model=User,
        related_name='posts'
    )
    content = TextField()

    class Meta:
        database = DATABASE
        order_by = ('-timestamp',)


def initialize():
    DATABASE.connect()
    DATABASE.create_tables([User, Post], safe=True)
    DATABASE.close()
from flask_wtf import Form
from wtforms import StringField, PasswordField, TextAreaField
from wtforms.validators import (DataRequired, Regexp, ValidationError, Email,
                                Length, EqualTo)

from models import User


def name_exists(form, field):
    if User.select().where(User.username == field.data).exists():
        raise ValidationError('User with that name already exists')


def email_exists(form, field):
    if User.select().where(User.email == field.data).exists():
                    raise ValidationError('User with that email already exists')


class RegisterForm(Form):
    username = StringField(
        'Username',
        validators=[
            DataRequired(),
            Regexp(
                r'^[a-zA-Z0-9_]+$',
                message=('Username should be one word, letters,'
                         'numbers and underscores only.')
            ),
            name_exists
        ])
    email = StringField(
        'Email',
        validators=[
            DataRequired(),
            Email(),
            email_exists
        ])
    password = PasswordField(
        'Password',
        validators=[
            DataRequired(),
            Length(min=2),
            EqualTo('password2', message='Passwords must match')
        ])
    password2 = PasswordField(
        'Confirm Password',
        validators=[DataRequired()])


class LoginForm(Form):
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])


class PostForm(Form):
    content = TextAreaField("What's up?", validators=[DataRequired()])
Y B
Y B
14,136 Points

If anyone can help me shed some light on this that would be a great help thanks.

Here is the traceback (not yet experienced enough to know the best way to utilise this)

:

peewee.OperationalError peewee.OperationalError: no such column: t1.content

Traceback (most recent call last) File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/flask/a

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

An error such as "no such column", implies the database is out of sync with your models. You can manually go into sqlite3 and add the missing "content" column to the "Post" table, Or you can remove your database and allow initialize() to recreate database tables that match your models.

Have you solved this?

Fernando Szymczak
Fernando Szymczak
17,372 Points

I'm having a similar issue. The traceback actually says:

peewee.OperationalError: no such table: user

It would be interesting to find out how to doing what you suggested. Manually going into sqlite3 and add the missing "content" column to the "Post" table, or in my case it seems 'user' to table.

Alternatively, when you say remove your database, do you mean simply delete the db file created when running the code ('social.db')?? If yes, i tried that and the same error comes up again. Any help would be much appreciated

Chris Freeman
Chris Freeman
Treehouse Moderator 68,423 Points

Hi Fernando, The difference between this post and your issue is that this post has a missing column which means that the database in tables exist but the columns don't match the models attributes.

Your issue seems to be that the tables them selves don't match. That implies that the database is not been initialize. Can you identify the code that initialized User?

Since your issue appears different please post your code and issue in a new question. Tag me in the question or in a comment so I can find it. Thanks.