【问题标题】:One-to-many Flask | SQLAlchemy一对多 Flask | SQL炼金术
【发布时间】:2014-10-12 01:37:01
【问题描述】:

我正在尝试使用 Flask 和 SQLAlchemy 创建一对多关系。

我希望一对多的关系是这样的:

“对于任何一部电影,都可以有多个角色”

这是我到目前为止所拥有的,但它现在以一对一的形式保存在我的数据库中。 (一部电影对一个角色,在数据库中为多个角色保存多次)

class Movie(db.Model):
    __tablename__ = "movies"
    id = db.Column('movies_id', db.Integer, primary_key=True)
    movie_type = db.Column('movie_type', db.Text())

    def __init__(self, movie_type):
        self.movie_type = movie_type

    def __repr__(self):
        return '<Movie %r>' % self.id

class Character(db.Model):
    __tablename__ = "characters"
    id = db.Column('character_id', db.Integer, primary_key=True) 
    character_description = db.Column('character_description', db.Text())

    movie_id = db.Column(db.Integer, db.ForeignKey('movies.movie_id'))
    movie = db.relationship('Movie', backref='characters', lazy='dynamic')

    def __init__(self, character_description, movie):
        self.character_description = character_description

        self.movie = movie

    def __repr__(self):
        return '<Character %r>' % self.id

我正在像这样保存到数据库中:

movie = models.movie(movie_type)
character = models.Character(character_description, movie)

db.session.add(movie)
db.session.add(character)
db.session.commit()

最终目标是能够查找某个角色在哪部电影中。如果您也可以帮助我解决这个问题,那就太好了!

提前谢谢。

【问题讨论】:

    标签: python flask sqlalchemy one-to-many flask-sqlalchemy


    【解决方案1】:

    嗯,我想你错过了电影中的角色关系 + 插入并不完全正确。

    还有一些小细节需要你小心。为什么电影的id是movieS_id,角色的id是character_id?

    此外,如果未指定,列的名称与变量的名称相同。

    例如,您可以这样做:

    character_description = db.Column(db.Text())
    

    不管怎样,在不改变这个细节的情况下,你可以试试这个:

    class Movie(db.Model):
        __tablename__ = "movies"
        id = db.Column('movies_id', db.Integer, primary_key=True)
        movie_type = db.Column('movie_type', db.Text())
        characters = db.relationship("Character", backref="movie", lazy='dynamic')
        def __init__(self, movie_type):
            self.movie_type = movie_type
    
        def __repr__(self):
            return '<Movie %r>' % self.id
    
    class Character(db.Model):
        __tablename__ = "characters"
        id = db.Column('character_id', db.Integer, primary_key=True) 
        character_description = db.Column('character_description', db.Text())
    
        movie_id = db.Column(db.Integer, db.ForeignKey('movies.movies_id'))
        movie = db.relationship('Movie')
    
        def __init__(self, character_description, movie):
            self.character_description = character_description
    
            self.movie = movie
    
        def __repr__(self):
            return '<Character %r>' % self.id
    

    插入

    c = Character(character_description='c')
    c2 = Character(character_description='c2')
    m = Movie(movie_type ='action')
    
    # link characters to movie
    m.characters.append(c)
    m.characters.append(c2)
    # or
    m.characters.extend([c,c2])
    
    db.session.add(m)
    # add characters
    db.session.add(c)
    db.session.add(c2)
    # or
    db.session.add_all([c,c2])
    # commit
    db.session.commit()
    

    【讨论】:

    • 感谢您的帮助,但这对我不起作用。我仍然得到一个一对一的(一个电影 id 与一个角色相关),而不是一个电影 id 与许多角色相关。关于我可能做错的任何想法?
    • 我需要在 init 中添加“电影”吗?如果是这样,插入时我该怎么做。 (例如 m = Movie(movie_type ='action')、c = Character(character_description='c')、m.characters.append(c) 等...)?
    • 哦,我想我颠倒了插入,抱歉。尝试做 db.session.add(m) 然后 db.session.add(c) 然后提交 :)
    • 这仍然会导致一对一:(首先,我是否需要在 init 中添加“self.movi​​e = movie”?如果需要,我是否在插入过程中添加它:m = Movie(movie_type ='action'), c = Character(character_description='c', movie), m.characters.append(c) (注意:我也试过我刚才提到的不工作)
    • 这部分不正确:movie = db.relationship('Movie') 你不需要这个。