【问题标题】:Flask/SQLAlchemy - error creating models with relationshipsFlask/SQLAlchemy - 创建具有关系的模型时出错
【发布时间】:2023-03-21 07:20:01
【问题描述】:

我在 shell 中使用这个 mysql 语句创建了一个表 users

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(40) NOT NULL,
  `email` varchar(120) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB;

还有一张表posts,上面有这个语句:

CREATE TABLE `posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `text` varchar(140) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_user_id` (`user_id`),
  CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;

我想在我的 Flask 应用程序中使用这些表。我创建了一个将posts 连接到users 的外键。它应该是与拥有许多帖子的用户的一对多关系。

在我的 python 代码中,我有以下模型:

class Users(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(40), unique=True)
    email = db.Column(db.String(120), unique=True)
    posts = db.relationship('Posts', backref='user', lazy='dynamic')

    def __init__(self, username, email):
        self.username = username
        self.email = email

    def __repr__(self):
        return '<User {}>'.format(self.username)


class Posts(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    text = db.Column(db.String(140))
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

但是,当我尝试运行我的 Flask 应用程序时,我不断收到错误消息:

sqlalchemy.exc.InvalidRequestError:一个或多个映射器未能 初始化 - 无法继续初始化其他映射器。 最初的例外是:无法确定之间的连接条件 关系 Users.posts 上的父/子表 - 没有外国 链接这些表的键。

但是我在mysql语句中创建了连接postsusers的外键。当我取出posts = db.relationship('Posts', backref='user', lazy='dynamic') 行时,一切正常,所以问题在于那段代码。我的设置的哪一部分有问题?

【问题讨论】:

    标签: python mysql flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    不确定表的初始创建有什么问题,但我会使用 sqlalchemy 的 create_all。请参阅heredocs。这样您就知道任何问题都不是初始 SQL 创建查询与模型定义的不同定义的问题。一直坚持使用 SQLAlchemy。

    您的模型定义看起来不错,除了 backref。我将它与我的模型定义进行了比较,我的反向引用总是表名。您将“用户”作为反向引用,它并没有真正出现在代码中的其他任何地方,所以我假设这是出了问题的地方。

    要强制定义表名,请在类定义中添加tablename;例如

    class User(db.model):
        __tablename__ = 'Users'
        id = db.Column(..
        .. more fields ..
        posts = db.relationship('Post', backref='Users', lazy='dynamic')
    

    我使用单数形式的类和复数形式的表名的约定,这样更容易看到事物是如何定义的,backref 指向什么等等。例如,注意上面的关系指向 class Post,而返回到 table 用户。现在定义中没有矛盾之处。

    【讨论】:

    • 太棒了,只需验证您的关系是否正常工作。可以使用“奇怪”关系定义创建表而不会出错,但最终无法按预期工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 2022-01-23
    • 2020-05-12
    • 1970-01-01
    相关资源
    最近更新 更多