sqlalchemy - 在 SQLAlchemy (+Flask) 中创建自引用 M2M 关系

标签 sqlalchemy flask self-reference

在尝试学习 Flask 的同时,我正在构建一个简单的 Twitter 克隆。这将包括用户关注其他用户的能力。我正在尝试通过 SQLAlchemy 设置关系数据库以允许这样做。

我想我需要一个关于用户的自引用多对多关系。继自 SQLAlchemy documentation我到达了:

#imports omitted    

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///twitclone.db'
db = SQLAlchemy(app)

Base = declarative_base()

user_to_user = Table("user_to_user", Base.metadata,
    Column("follower_id", Integer, ForeignKey("user.id"), primary_key=True),
    Column("followed_id", Integer, ForeignKey("user.id"), primary_key=True)
)

class User(db.Model):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    name = Column(String, unique=False)
    handle = Column(String, unique=True)
    password = Column(String, unique=False)
    children = relationship("tweet")
    following = relationship("user",
                    secondary=user_to_user,
                    primaryjoin=id==user_to_user.c.follower_id,
                    secondaryjoin=id==user_to_user.c.followed_id,
                    backref="followed_by"
    )

#Tweet class goes here

db.create_all()

if __name__ == "__main__":
    app.run()

运行此代码会导致创建数据库时没有任何错误消息。然而,将用户连接到用户的整个部分(表格)被简单地省略了。这是用户表的定义:

CREATE TABLE user (
    id INTEGER NOT NULL, 
    name VARCHAR, 
    handle VARCHAR, 
    password VARCHAR, 
    PRIMARY KEY (id), 
    UNIQUE (handle)
)

为什么 SQLAlchemy 不为用户创建自引用关系?

注意:我是 Flask 和 SQLAlchemy 的新手,可能会遗漏一些明显的东西。

最佳答案

好吧,我似乎混淆了两种不同的使用 SQLAlchemy 和 Flask 的方式:SQLAlchemy 的声明式扩展和 flask-sqlalchemy 扩展。两者在功能上相似,不同之处在于 flask 扩展有一些好东西,比如 session 处理。这就是我重写代码以严格使用 flask-sqlalchemy 的方式。

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from datetime import datetime

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///kwek.db'
db = SQLAlchemy(app)

#Table to handle the self-referencing many-to-many relationship for the User class:
#First column holds the user who follows, the second the user who is being followed.
user_to_user = db.Table('user_to_user',
    db.Column("follower_id", db.Integer, db.ForeignKey("user.id"), primary_key=True),
    db.Column("followed_id", db.Integer, db.ForeignKey("user.id"), primary_key=True)
)


class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=False)
    handle = db.Column(db.String(16), unique=True)
    password = db.Column(db.String, unique=False)
    kweks = db.relationship("Kwek", lazy="dynamic")
    following = db.relationship("User",
                    secondary=user_to_user,
                    primaryjoin=id==user_to_user.c.follower_id,
                    secondaryjoin=id==user_to_user.c.followed_id,
                    backref="followed_by"
    )

    def __repr__(self):
        return '<User %r>' % self.name


class Kwek(db.Model):
    __tablename__ = 'kwek'
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(140), unique=False)
    post_date = db.Column(db.DateTime, default=datetime.now())
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    def __repr__(self):
        return '<Kwek %r>' % self.content

if __name__ == "__main__":
    app.run()

关于sqlalchemy - 在 SQLAlchemy (+Flask) 中创建自引用 M2M 关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20830118/

相关文章:

c# - 使用 EF Core 5.0 加载自引用实体(只需将父级及其子级置于其导航属性中即可)

mysql - 使用自引用列更新 MySQL 表

postgresql - Insert 能否锁定选择/选择计数 (*) 或其他方式?

python - 在 Flask-SQLAlchemy 模型类中使用数据类装饰器?

python - 在 RESTful Web 服务中,服务器需要很长时间才能响应是否可以接受?

apache - 由于 session 重置,Apache Flask 中的 CSRF token 不匹配

javascript - 从自引用数组转换为树中的嵌套数组

postgresql - 如何使 Flask SQLAlchemy 重用数据库连接?

python - SQLAlchemy 错误 : MySQL Connection not available

windows - 如何修复 Apache 服务器 (Windows) 中的导入 ssl 错误