56

我正在关注关于声明关于一对多关系的模型的 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'))

现在我想知道如何使用这种模型将新记录插入数据库。我假设我需要一个构造函数init,但我很难理解它应该如何实现和使用。我这里的主要问题是 Person 依赖于 Address 并且 Address 对 Person 有 ForeignKey,所以它应该提前知道 Person。

请帮助我了解它应该如何执行。

先感谢您。

4

4 回答 4

85

您不需要编写构造函数,您可以将实例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
于 2013-05-08T07:22:47.417 回答
5

我在这里和其他地方收集了信息,并找到了 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)
于 2021-03-08T13:33:53.173 回答
3

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

因此,带有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 = tuple()):
        self.id = id
        self.name = name
        self.addresses = addresses

所以这个 Person 类将需要一个 id、一个名称和一个包含 Address 类型对象的列表。我将默认值保留为空列表。

希望能帮助到你。:)

于 2015-03-16T14:23:36.893 回答
0

除了所有先前的答案之外,在与 的一对一关系中uselist=False,例如:

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

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'))

只有下一种方法有助于插入记录:

p = Person(name='foo')
a = Address(email='foo@bar.com', person=p)  # Adding created person directly to Address's backref
于 2021-09-10T18:32:01.210 回答