Cha0 Cha0 - 3 months ago 10
Python Question

Flask-SQLAlchemy - Backref isn't working, value is None

I think I have the same issue as here on SO. Using python 3.5, flask-sqlalchemy, and sqlite. I am trying to establish a one (User) to many (Post) relationship.

class User(db_blog.Model):
id = db_blog.Column(db_blog.Integer, primary_key=True)
nickname = db_blog.Column(db_blog.String(64), index=True, unique=True)
email = db_blog.Column(db_blog.String(120), unique=True)
posts = db_blog.relationship('Post', backref='author', lazy='dynamic')

def __repr__(self):
return '<User: {0}>'.format(self.nickname)

class Post(db_blog.Model):
id = db_blog.Column(db_blog.Integer, primary_key=True)
body = db_blog.Column(db_blog.String(2500))
title = db_blog.Column(db_blog.String(140))
user_id = db_blog.Column(db_blog.Integer, db_blog.ForeignKey('user.id'))

def __init__(self, body, title, **kwargs):
self.body = body
self.title = title

def __repr__(self):
return '<Title: {0}\nPost: {1}\nAuthor: {2}>'.format(self.title, self.body, self.author)


Author is None.

>>> u = User(nickname="John Doe", email="jdoe@email.com")
>>> u
<User: John Doe>
>>> db_blog.session.add(u)
>>> db_blog.session.commit()
>>> u = User.query.get(1)
>>> u
<User: John Doe>
>>> p = Post(body="Body of post", title="Title of Post", author=u)
>>> p
<Title: Title of Post
Post: Body of post
Author: None> #Here I expect- "Author: John Doe>"


I get the same result after session add/commit of the post and so can't find the post author.

Answer

If you add the newly created post to the posts attribute of the user, it will work:

>>> u = User(nickname="John Doe", email="jdoe@email.com")
>>> u
<User: John Doe>
>>> db_blog.session.add(u)
>>> p = Post(body="Body of post", title="Title of Post")
>>> p
<Title: Title of Post
Post: Body of post
Author: None>
>>> db_blog.session.add(p)
>>> db_blog.session.commit()
>>> u.posts.append(p)
>>> p
<Title: Title of Post
Post: Body of post
Author: <User: John Doe>>
>>> p.author
<User: John Doe>

The reason your code doesn't work as-is, is because you've defined an __init__ constructor for your Post class, and this doesn't consider the author field at all, so Python doesn't know what to do with that author parameter.

Comments