在 SQLAlchemy 中链接表 foreign_keys 错误 [Flask]
Linking tables in SQLAclhemy foreign_keys error [Flask]
我有两个模型 Post 和类别。
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
body = db.Column(db.Text)
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
body_html = db.Column(db.Text)
comments = db.relationship('Comment', backref='post', lazy='dynamic')
category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
category = db.relationship('Category',
backref=db.backref('posts', lazy='dynamic'))
@staticmethod
def on_changed_body(target, value, oldvalue, initiator):
allowed_tags = ['a', 'abbr', 'acronym', 'b', 'blackquote', 'code', 'em', 'i', 'li', 'ol', 'pre', 'strong',
'ul', 'h1', 'h2', 'h3', 'p']
target.body_html = bleach.linkify(bleach.clean(
markdown(value, output_form='html'),
tags=allowed_tags, strip=True))
def to_json(self):
json_post = {
'url': url_for('api.get_post', id=self.author_id, _external=True),
'title': self.title,
'body': self.body,
'body_html': self.body_html,
'author': url_for('api.get_user', id=self.author_id,
_external=True),
'comments': url_for('api.get_post_comments', id=self.id, _external=True),
'comment_count': self.comments.count(),
'category': self.category,
'category_id': self.category_id
}
return json_post
@staticmethod
def from_json(json_post):
body = json_post.get('body')
if body is None or body == '':
raise ValidationError('post does not have a body')
return Post(body=body)
db.event.listen(Post.body, 'set', Post.on_changed_body)
class Category(db.Model):
__tablename__ = 'categories'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
def to_json(self):
json_category = {
'category_id': self.id,
'category_name': str(self.name),
'category_url': url_for('api.get_category', id=self.id, _external=True),
}
return json_category
def __str__ (self):
return '%s' % self.name
我已通过将以下内容添加到我的 Post 模型,link 将 Post 成功地编辑到他们的类别中,
category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
category = db.relationship('Category',
backref=db.backref('posts', lazy='dynamic'))
效果很好!现在我可以为我的帖子选择任何类别,并可以使用 /category/<name>
在各自的类别下查看它们。现在我正在尝试创建一个 API (json),正如您从具有 to_json 函数的模型中看到的那样。我创建了一个视图来查看所有帖子及其信息
@api.route('/posts/')
def get_posts():
page = request.args.get('page', 1, type=int)
pagination = Post.query.paginate(
page, per_page=current_app.config['POSTS_PER_PAGE'],
error_out=False)
posts = pagination.items
prev = None
if pagination.has_prev:
prev = url_for('api.get_posts', page=page-1, _external=True)
next = None
if pagination.has_next:
next = url_for('api.get_posts', page=page+1, _external=True)
return jsonify({
'posts': [post.to_json() for post in posts],
'prev': prev,
'next': next,
'count': pagination.total
})
但现在我正在尝试创建一个视图来查看每个类别 category/<name>/posts/
的所有帖子,所以我认为我需要 link 将类别增加到 Post,因为我 link编辑 Post 到类别,以便能够看到各自类别下的所有帖子。所以我尝试将以下内容添加到类别模型中:
post_id = db.Column(db.Integer, db.ForeignKey('posts.id'))
然后创建了一个视图来查看 JSON 类别下的帖子,但我收到以下错误。
InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Original exception was: Could not determine join condition between parent/child tables on relationship Post.category - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
起初我假设它应该是多对多关系,但它是 POSTS 的类别,所以它应该是一对多关系,与我 linked 时完全相同发布到类别。我很困惑,我需要添加或修复什么才能使这项工作正常进行?
因此,在@dirn 的帮助下,我通过访问我在 Post class 类别下 backref=db.backref('posts', lazy='dynamic'))
在我的路线中 category/<name>/posts/
哪个看起来像
@api.route('/category/<int:id>/posts/')
def get_category_posts(id):
category = Category.query.get_or_404(id)
page = request.args.get('page', 1, type=int)
pagination = category.posts.order_by(Post.timestamp.asc()).paginate(
page, per_page=current_app.config['COMMENTS_PER_PAGE'],
error_out=False)
posts = pagination.items
prev = None
if pagination.has_prev:
prev = url_for('api.get_category_posts', page=page - 1, _external=True)
next = None
if pagination.has_next:
next = url_for('api.get_category_posts', page=page + 1, _external=True)
return jsonify({
'posts': [post.to_json() for post in posts],
'prev': prev,
'next': next,
'count': pagination.total
})
我访问它的方式是 category.posts
在
pagination = category.posts.order_by(Post.timestamp.asc())
我有两个模型 Post 和类别。
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
body = db.Column(db.Text)
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
body_html = db.Column(db.Text)
comments = db.relationship('Comment', backref='post', lazy='dynamic')
category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
category = db.relationship('Category',
backref=db.backref('posts', lazy='dynamic'))
@staticmethod
def on_changed_body(target, value, oldvalue, initiator):
allowed_tags = ['a', 'abbr', 'acronym', 'b', 'blackquote', 'code', 'em', 'i', 'li', 'ol', 'pre', 'strong',
'ul', 'h1', 'h2', 'h3', 'p']
target.body_html = bleach.linkify(bleach.clean(
markdown(value, output_form='html'),
tags=allowed_tags, strip=True))
def to_json(self):
json_post = {
'url': url_for('api.get_post', id=self.author_id, _external=True),
'title': self.title,
'body': self.body,
'body_html': self.body_html,
'author': url_for('api.get_user', id=self.author_id,
_external=True),
'comments': url_for('api.get_post_comments', id=self.id, _external=True),
'comment_count': self.comments.count(),
'category': self.category,
'category_id': self.category_id
}
return json_post
@staticmethod
def from_json(json_post):
body = json_post.get('body')
if body is None or body == '':
raise ValidationError('post does not have a body')
return Post(body=body)
db.event.listen(Post.body, 'set', Post.on_changed_body)
class Category(db.Model):
__tablename__ = 'categories'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
def to_json(self):
json_category = {
'category_id': self.id,
'category_name': str(self.name),
'category_url': url_for('api.get_category', id=self.id, _external=True),
}
return json_category
def __str__ (self):
return '%s' % self.name
我已通过将以下内容添加到我的 Post 模型,link 将 Post 成功地编辑到他们的类别中,
category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
category = db.relationship('Category',
backref=db.backref('posts', lazy='dynamic'))
效果很好!现在我可以为我的帖子选择任何类别,并可以使用 /category/<name>
在各自的类别下查看它们。现在我正在尝试创建一个 API (json),正如您从具有 to_json 函数的模型中看到的那样。我创建了一个视图来查看所有帖子及其信息
@api.route('/posts/')
def get_posts():
page = request.args.get('page', 1, type=int)
pagination = Post.query.paginate(
page, per_page=current_app.config['POSTS_PER_PAGE'],
error_out=False)
posts = pagination.items
prev = None
if pagination.has_prev:
prev = url_for('api.get_posts', page=page-1, _external=True)
next = None
if pagination.has_next:
next = url_for('api.get_posts', page=page+1, _external=True)
return jsonify({
'posts': [post.to_json() for post in posts],
'prev': prev,
'next': next,
'count': pagination.total
})
但现在我正在尝试创建一个视图来查看每个类别 category/<name>/posts/
的所有帖子,所以我认为我需要 link 将类别增加到 Post,因为我 link编辑 Post 到类别,以便能够看到各自类别下的所有帖子。所以我尝试将以下内容添加到类别模型中:
post_id = db.Column(db.Integer, db.ForeignKey('posts.id'))
然后创建了一个视图来查看 JSON 类别下的帖子,但我收到以下错误。
InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Original exception was: Could not determine join condition between parent/child tables on relationship Post.category - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
起初我假设它应该是多对多关系,但它是 POSTS 的类别,所以它应该是一对多关系,与我 linked 时完全相同发布到类别。我很困惑,我需要添加或修复什么才能使这项工作正常进行?
因此,在@dirn 的帮助下,我通过访问我在 Post class 类别下 backref=db.backref('posts', lazy='dynamic'))
在我的路线中 category/<name>/posts/
哪个看起来像
@api.route('/category/<int:id>/posts/')
def get_category_posts(id):
category = Category.query.get_or_404(id)
page = request.args.get('page', 1, type=int)
pagination = category.posts.order_by(Post.timestamp.asc()).paginate(
page, per_page=current_app.config['COMMENTS_PER_PAGE'],
error_out=False)
posts = pagination.items
prev = None
if pagination.has_prev:
prev = url_for('api.get_category_posts', page=page - 1, _external=True)
next = None
if pagination.has_next:
next = url_for('api.get_category_posts', page=page + 1, _external=True)
return jsonify({
'posts': [post.to_json() for post in posts],
'prev': prev,
'next': next,
'count': pagination.total
})
我访问它的方式是 category.posts
在
pagination = category.posts.order_by(Post.timestamp.asc())