Python 存储对SQLAlchemy多对多关联表中其他行的引用

Python 存储对SQLAlchemy多对多关联表中其他行的引用,python,orm,sqlalchemy,many-to-many,flask-sqlalchemy,Python,Orm,Sqlalchemy,Many To Many,Flask Sqlalchemy,我在做一个SQLAlchemy的项目。让我们假设为了简化这个问题,有三个表在使用——博客帖子、用户和用户每日帖子。前两个看起来像这样: 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(d

我在做一个SQLAlchemy的项目。让我们假设为了简化这个问题,有三个表在使用——博客帖子、用户和用户每日帖子。前两个看起来像这样:

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'))
对于第三个表,期望它的主键是一个user_id和一个date,比如date是一个整数,一个like列,以及一个应该跟踪该特定日期的博客文章的列。当一篇文章是like时,like会传播到此表和Users表,但Blog_posts不会存储它。我原本以为date应该是外键,但事实证明,在原始表中有一个唯一性约束,它们在Blog_posts表中不会是唯一的,所以我认为设计应该是这样的:

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 = ?
对于博客文章,我尝试:

db.relationship('Blog_posts', lazy='dynamic', backref=db.backref('posts', lazy='dynamic'))
认为这可能允许我添加一个博客帖子列表,但这会产生错误:

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.

我已经看到了一些关于这个错误的帖子,但我真的不明白primaryjoin表达式是什么,因为我是你能从数据库高手那里得到的最远的。有人能解释一下主要连接是什么以及为什么吗?或者至少我做错了什么?如果有一个不同的SQLAlchemy习惯用法更适合这个目的,我很想听听。非常感谢您抽出时间

在许多情况下,两个类之间需要一个关联表。但是看看你的案例,我相信你只需要一个column_属性或者做一个简单的查询就足够了

在您的情况下,您将拥有:

每篇文章只有一个创作者,多对一也是如此 关系

喜欢的人不能不在用户身上,但你可以有一个 列属性,计算有多少喜欢

最后,喜欢与访客和帖子更相关。那么你呢 需要另一个模型来保存有关 访客。然后与用户建立关系

试试这个:

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')]
您可以在上看到关于多对多的一些信息