在 SQLAlchemy 多对多关联中存储对其他行的引用 table
Storing reference to other rows in SQLAlchemy Many-to-Many association table
我正在使用 SQLAlchemy 开发一个项目。假设(为了简化问题)有三个 table 在起作用——Blog_posts、Users 和 Users_daily_posts。前两个看起来像这样:
class Blog_posts(db.Model):
__tablename__ = 'Blog_posts'
post_id = db.Column(db.Integer(), primary_key = True)
date = db.Column(db.Integer())
creator_id = db.Column(db.Integer())
class Users(db.Model):
__tablename__ = 'Users'
user_id = db.Column(db.Integer(), primary_key = True)
likes = db.Column(db.Integer())
users_daily_posts = db.relationship('Users_daily_posts', lazy='dynamic', backref=db.backref('user', lazy='dynamic'))
对于第三个 table,期望它具有作为主键的 user_id 和一个日期(比如日期是一个整数),一个表示喜欢的列,以及一个应该跟踪那个特定日期的博客post。当 post 被点赞时,点赞会传播到此 table 和用户 table,但 Blog_posts 不会存储它。本来以为date应该是外键,结果原来table里面有唯一性约束,在Blog_poststable里面就不唯一了,所以我认为设计应该是这样的:
class Users_daily_posts(db.Model):
__tablename__ = 'Users_daily_posts'
user_id = db.Column(db.Integer(), db.ForeignKey('Users.user_id', ondelete="CASCADE"), primary_key = True)
date = db.Column(db.Integer(), primary_key = True)
likes = db.Column(db.Integer())
blog_posts = ?
对于blog_posts,我试过:
db.relationship('Blog_posts', lazy='dynamic', backref=db.backref('posts', lazy='dynamic'))
认为这可能允许我添加博客列表 post,但这给出了错误:
ArgumentError: Could not determine join condition between parent/child tables on relationship Users_daily_posts.blog_posts. Specify a 'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is needed as well.
我已经看到几个关于这个错误的 post,但我真的不明白 primaryjoin 表达式是什么,因为我是你能从数据库高手那里得到的最深入的信息.有人可以解释主要连接是什么以及为什么吗?或者至少我做错了什么?如果有更适合此目的的不同 SQLAlchemy 惯用语,我很想听听。非常感谢您的宝贵时间!
在很多情况下,您需要在两个 类 之间建立关联 table。但是看你的情况,我相信你只需要一个column_property或者做一个简单的查询就足够了。
在您的情况下,您将拥有:
每个 post 只有一个创作者或作者,多对一也是如此
关系;
"likes"不能不在用户身上,但你可以有一个
属性 列,计算点赞数;
最后,"likes"与访客和post的关联度更高。所以你
将需要另一个模型来保存有关
的信息
访客。然后和用户建立关系
试试这个:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
class Blog_post(db.Model):
__tablename__ = 'Blog_posts'
post_id = db.Column(db.Integer, primary_key = True)
creator_id = db.Column(db.Integer, db.ForeignKey('Users.user_id'), nullable=False)
headline = db.Column(db.String(255), nullable=False)
date = db.Column(db.Date, nullable=False)
likes = db.Column(db.Integer)
def __init__(self, headline, body,creator_id):
self.headline = headline
self.creator_id = creator_id
self.date = datetime.datetime.today()
class User(db.Model):
__tablename__ = 'Users'
user_id = db.Column(db.Integer(), primary_key = True)
user_name = db.Column(db.String(80), unique=True)
users_posts = db.column_property(
db.select([db.func.count(Blog_post.post_id)]).\
where(Blog_post.creator_id==user_id).\
correlate_except(Blog_post)
)
def __init__(self, user_name):
self.user_name = user_name
正在测试...
>>> db.create_all()
>>> u = User('dedeco')
>>> db.session.add(u)
>>> db.session.commit()
>>>
>>> p = Blog_post('I am dedeco 1','About dedeco 1',u.user_id)
>>> db.session.add(p)
>>> p = Blog_post('I am dedeco 2','About dedeco 2',u.user_id)
>>> db.session.add(p)
>>> p = Blog_post('I am dedeco 3','About dedeco 3',u.user_id)
>>> db.session.add(p)
>>> db.session.commit()
>>> u.users_posts
3
查询:
>>> d = db.session.query(db.func.count(Blog_post.post_id),db.func.strftime('%d/%m/%Y', Blog_post.date)).filter(Blog_post.creator_id==u.user_id).group_by(db.func.strftime('%d/%m/%Y', Blog_post.date))
>>> d.all()
[(3, u'04/11/2015')]
上看到一些关于多对多的信息
我正在使用 SQLAlchemy 开发一个项目。假设(为了简化问题)有三个 table 在起作用——Blog_posts、Users 和 Users_daily_posts。前两个看起来像这样:
class Blog_posts(db.Model):
__tablename__ = 'Blog_posts'
post_id = db.Column(db.Integer(), primary_key = True)
date = db.Column(db.Integer())
creator_id = db.Column(db.Integer())
class Users(db.Model):
__tablename__ = 'Users'
user_id = db.Column(db.Integer(), primary_key = True)
likes = db.Column(db.Integer())
users_daily_posts = db.relationship('Users_daily_posts', lazy='dynamic', backref=db.backref('user', lazy='dynamic'))
对于第三个 table,期望它具有作为主键的 user_id 和一个日期(比如日期是一个整数),一个表示喜欢的列,以及一个应该跟踪那个特定日期的博客post。当 post 被点赞时,点赞会传播到此 table 和用户 table,但 Blog_posts 不会存储它。本来以为date应该是外键,结果原来table里面有唯一性约束,在Blog_poststable里面就不唯一了,所以我认为设计应该是这样的:
class Users_daily_posts(db.Model):
__tablename__ = 'Users_daily_posts'
user_id = db.Column(db.Integer(), db.ForeignKey('Users.user_id', ondelete="CASCADE"), primary_key = True)
date = db.Column(db.Integer(), primary_key = True)
likes = db.Column(db.Integer())
blog_posts = ?
对于blog_posts,我试过:
db.relationship('Blog_posts', lazy='dynamic', backref=db.backref('posts', lazy='dynamic'))
认为这可能允许我添加博客列表 post,但这给出了错误:
ArgumentError: Could not determine join condition between parent/child tables on relationship Users_daily_posts.blog_posts. Specify a 'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is needed as well.
我已经看到几个关于这个错误的 post,但我真的不明白 primaryjoin 表达式是什么,因为我是你能从数据库高手那里得到的最深入的信息.有人可以解释主要连接是什么以及为什么吗?或者至少我做错了什么?如果有更适合此目的的不同 SQLAlchemy 惯用语,我很想听听。非常感谢您的宝贵时间!
在很多情况下,您需要在两个 类 之间建立关联 table。但是看你的情况,我相信你只需要一个column_property或者做一个简单的查询就足够了。
在您的情况下,您将拥有:
每个 post 只有一个创作者或作者,多对一也是如此 关系;
"likes"不能不在用户身上,但你可以有一个
属性 列,计算点赞数;最后,"likes"与访客和post的关联度更高。所以你
将需要另一个模型来保存有关
的信息 访客。然后和用户建立关系
试试这个:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
class Blog_post(db.Model):
__tablename__ = 'Blog_posts'
post_id = db.Column(db.Integer, primary_key = True)
creator_id = db.Column(db.Integer, db.ForeignKey('Users.user_id'), nullable=False)
headline = db.Column(db.String(255), nullable=False)
date = db.Column(db.Date, nullable=False)
likes = db.Column(db.Integer)
def __init__(self, headline, body,creator_id):
self.headline = headline
self.creator_id = creator_id
self.date = datetime.datetime.today()
class User(db.Model):
__tablename__ = 'Users'
user_id = db.Column(db.Integer(), primary_key = True)
user_name = db.Column(db.String(80), unique=True)
users_posts = db.column_property(
db.select([db.func.count(Blog_post.post_id)]).\
where(Blog_post.creator_id==user_id).\
correlate_except(Blog_post)
)
def __init__(self, user_name):
self.user_name = user_name
正在测试...
>>> db.create_all()
>>> u = User('dedeco')
>>> db.session.add(u)
>>> db.session.commit()
>>>
>>> p = Blog_post('I am dedeco 1','About dedeco 1',u.user_id)
>>> db.session.add(p)
>>> p = Blog_post('I am dedeco 2','About dedeco 2',u.user_id)
>>> db.session.add(p)
>>> p = Blog_post('I am dedeco 3','About dedeco 3',u.user_id)
>>> db.session.add(p)
>>> db.session.commit()
>>> u.users_posts
3
查询:
>>> d = db.session.query(db.func.count(Blog_post.post_id),db.func.strftime('%d/%m/%Y', Blog_post.date)).filter(Blog_post.creator_id==u.user_id).group_by(db.func.strftime('%d/%m/%Y', Blog_post.date))
>>> d.all()
[(3, u'04/11/2015')]
上看到一些关于多对多的信息