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 trialRyan Mooney
Data Analysis Techdegree Student 14,265 PointsKeyError with the class Relationship(Model)
I am running this on my local computer instead of through workspaces. I have found a few changes I needed to make such as "related_name" is now "backref" (due to the updated version of peewee. So far, I cannot figure out why I am getting a system breaking error. Here is the full error from the command line:
Traceback (most recent call last): File "app.py", line 111, in <module> models.initialize() File "D:\Programming\Python\teamTreehouse\flaskSocial\venv\models.py", line 86, in initialize DATABASE.create_tables([User, Post, Relationship], safe=True) File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 3286, in create_ tables model.create_table(options) File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 6595, in create_ table cls.schema.create_all(safe, **options) File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 5732, in create all self.create_indexes(safe=safe) File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 5645, in create_ indexes for query in self.create_indexes(safe=safe): File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 5634, in _create _indexes for index in self.model._meta.fields_to_index()] File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 6011, in fields to_index fields.append(self.combined[part]) KeyError: 'f' PS D:\Programming\Python\teamTreehouse\flaskSocial\venv> python app.py Traceback (most recent call last): File "app.py", line 111, in <module> models.initialize() File "D:\Programming\Python\teamTreehouse\flaskSocial\venv\models.py", line 86, in initialize DATABASE.create_tables([User, Post, Relationship], safe=True) File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 3286, in create_ tables model.create_table(options) File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 6595, in create_ table cls.schema.create_all(safe, **options) File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 5732, in create all self.create_indexes(safe=safe) File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 5645, in create_ indexes for query in self.create_indexes(safe=safe): File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 5634, in _create _indexes for index in self.model._meta.fields_to_index()] File "d:\Programming\Python\teamTreehouse\flaskSocial\venv\lib\site-packages\peewee.py", line 6011, in fields to_index fields.append(self.combined[part]) KeyError: 'f'
Here is my models.py file: import datetime
from flask_bcrypt import generate_password_hash from flask_bcrypt import check_password_hash from flask_login import UserMixin 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)
)
def following(self):
"""The users that we are following."""
return (
User.select().join(
Relationship, on=Relationship.to_user
).where(
Relationship.from_user == self
)
)
def followers(self):
"""Get Users following the current user"""
return (
User.select().join(
Relationship, on=Relationship.from_user
).where(
Relationship.to_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( model=User, backref='posts' ) content = TextField()
class Meta:
database = DATABASE
order_by = ('-timestamp',)
class Relationship(Model): from_user = ForeignKeyField(User, backref='relationships') to_user = ForeignKeyField(User, backref='related_to')
class Meta:
database = DATABASE
indexes = (
(('from_user', 'to_user'), True)
)
def initialize(): DATABASE.connect() DATABASE.create_tables([User, Post, Relationship], safe=True) DATABASE.close()
I have compared this to the actual PeeWee docs (http://docs.peewee-orm.com/en/latest/peewee/models.html#single-column-indexes-and-constraints) but cannot find the error. Everything appears to be properly strucutured
Ryan Mooney
Data Analysis Techdegree Student 14,265 Pointssorry, here you go
models.py
import datetime
from flask_bcrypt import generate_password_hash
from flask_bcrypt import check_password_hash
from flask_login import UserMixin
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)
)
def following(self):
"""The users that we are following."""
return (
User.select().join(
Relationship, on=Relationship.to_user
).where(
Relationship.from_user == self
)
)
def followers(self):
"""Get Users following the current user"""
return (
User.select().join(
Relationship, on=Relationship.from_user
).where(
Relationship.to_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(
model=User,
backref='posts'
)
content = TextField()
class Meta:
database = DATABASE
order_by = ('-timestamp',)
class Relationship(Model):
from_user = ForeignKeyField(User, backref='relationships')
to_user = ForeignKeyField(User, backref='related_to')
class Meta:
database = DATABASE
indexes = (
(('from_user', 'to_user'), True)
)
def initialize():
DATABASE.connect()
DATABASE.create_tables([User, Post, Relationship], safe=True)
DATABASE.close()
app.py
from flask import (Flask, g, render_template, flash,
redirect, url_for)
from flask_bcrypt import check_password_hash
from flask_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 = 'xVQFFPq798Z6JejNkfxHS'
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 DB before each request"""
g.db = models.DATABASE
g.db.connect()
g.user = current_user
@app.after_request
def after_request(response):
"""Close the DB 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 successfully 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 have 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 have 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='ryan',
email='ryan@ryan.com',
password='password',
admin=True
)
except ValueError:
pass
app.run(debug=DEBUG, port=PORT, host=HOST)
I did rerun through the code. If I remove the "Relationship" from the DATABASE.create_tables, it runs fine. That leads me to believe there is something wrong with the Relationship class.
Up to this point, any variation from the course (due to version changes of PeeWee), was easily found in the PeeWee docs as mentioned in my original post. I am truly stumped.
Josh Keenan
20,315 PointsJosh Keenan
20,315 PointsCan you put three backtick ` characters at the start and end of the code please. And could you add your app.py too