在sqlalchemy中插入具有一对多关系的新记录

时间:2013-05-08 05:33:36

标签: python sqlalchemy foreign-keys relationship flask-sqlalchemy

我正在关注declaring models关于一对多关系的flask-sqlalchemy教程。示例代码如下:

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    addresses = db.relationship('Address', backref='person',
                                lazy='dynamic')

class Address(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(50))
    person_id = db.Column(db.Integer, db.ForeignKey('person.id'))

现在我想知道如何使用这样的模型将新记录插入到DB中。我假设我需要一个构造函数 init ,但我很难理解它应该如何实现和使用。我这里的主要问题是Person依赖于地址和地址有ForeignKey to Person,所以它应该事先知道Person。

Plase帮助我理解它应该如何进行。

提前谢谢。

4 个答案:

答案 0 :(得分:59)

您不需要编写构造函数,您可以将addresses实例上的Person属性视为列表:

a = Address(email='foo@bar.com')
p = Person(name='foo')
p.addresses.append(a)

或者您可以将地址列表传递给Person构造函数

a = Address(email='foo@bar.com')
p = Person(name='foo', addresses=[a])

在任何一种情况下,您都可以访问Person实例上的地址,如下所示:

db.session.add(p)
db.session.add(a)
db.session.commit()
print p.addresses.count() # 1
print p.addresses[0] # <Address object at 0x10c098ed0>
print p.addresses.filter_by(email='foo@bar.com').count() # 1

答案 1 :(得分:3)

在某些情况下,会出现“列表对象没有属性_sa_instance_state”之类的异常。

a = Address(email='foo@bar.com')
p = Person(name='foo', addresses=a)

解决此异常。

答案 2 :(得分:1)

在研究这个模型时,最重要的是要了解这个模型具有一对多关系的事实,即一个Person有多个地址,我们将把这些地址存储在一个列表中。

因此,具有 init 的Person类看起来像这样。

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    addresses = db.relationship('Address', backref='person',
                            lazy='dynamic')

    def __init__(self,id,name,addresses = []):
        self.id = id
        self.name = name
        self.addresses = addresses

因此,此Person类将需要一个id,一个名称和一个包含Address类型对象的列表。我保留了默认值为空列表。

希望它有所帮助。 :)

答案 3 :(得分:1)

我在这里和其他地方收集了信息,并找到了 3 种方法。在此模型示例中(与问题相同):

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    addresses = db.relationship('Address', backref='person',
                                lazy='dynamic')

class Address(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(50))
    person_id = db.Column(db.Integer, db.ForeignKey('person.id'))

1.

a = Address(email='foo@bar.com')
p = Person(name='foo', addresses=[a])

2.

p = Person(name='foo')
a = Address(email='foo@bar.com', person_id=p.id)

3.

a = Address(email='foo@bar.com')
p = Person(name='foo')
p.addresses.append(a)