簡體   English   中英

在SQLAlchemy多對多關聯表中存儲對其他行的引用

[英]Storing reference to other rows in SQLAlchemy Many-to-Many association table

我正在SQLAlchemy中的一個項目。 我們說(為簡化問題),有三個表在起作用-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'))

對於第三張表,期望它具有一個user_id和一個日期(例如date是一個整數),一個表示喜歡的列以及一個應該跟蹤該特定日期的博客帖子作為主鍵。 當喜歡某個帖子時,類似內容會傳播到該表和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 = ?

對於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_property或做一個簡單的查詢就足夠了。

就您而言,您將擁有:

  • 每個帖子只有一個創建者或作者,因此多對一關系;

  • “贊”不能不被用戶接受,但是您可以
    計算有多少喜歡的專欄屬性;

  • 最后,“喜歡”與訪問者和帖子更多相關。 那么你
    將需要其他模型以保留有關
    訪客。 然后與用戶建立關系。

嘗試這個:

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文檔上看到有關多對多的一些信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM