Flask / SQLAlchemy - 使用关系创建模型时出错

时间:2016-01-11 04:37:23

标签: python mysql flask sqlalchemy flask-sqlalchemy

我在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语句中创建了将posts连接到users的外键。当我拿出行posts = db.relationship('Posts', backref='user', lazy='dynamic')时,一切正常,所以问题在于那段代码。我的设置的哪一部分是错的?

1 个答案:

答案 0 :(得分:1)

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

除了backref之外,您的模型定义似乎没问题。我将它与我的模型定义进行了比较,我的backrefs总是表名。你有&#39;用户&#39;作为一个背景,它并没有真正出现在代码的任何其他地方,所以我假设出现问题。

要强制定义表名,请将 tablename 添加到类定义中; e.g。

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

我使用单数形式的约定,以及复数形式的表名,这样可以更容易地看到事物的定义方式,背景指向的内容等等。例如,请注意上述关系指向< em> class Post ,而backref到用户。现在定义中没有矛盾心理。