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

时间:2023-01-06 17:04:14

I'm following the flask-sqlalchemy tutorial on declaring models regarding one-to-many relationship. The example code is as follows:

我正在遵循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'))

Now I'm wondering how to insert new records into DB using such model. I assume I need a constructor init, but I have difficulties to understand how it should be implemented and used. The main problem for me here is that Person depends on Address and Address has ForeignKey to Person, so it should know about the Person in advance.

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

Plase help me to understand how it should be performed.

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

Thank you in advance.

先感谢您。

3 个解决方案

#1


43  

You dont need to write a constructor, you can either treat the addresses property on a Person instance as a list:

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

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

Or you can pass a list of addresses to the Person constructor

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

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

In either case you can then access the addresses on your Person instance like so:

在任何一种情况下,您都可以访问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

#2


3  

In some cases there is have an Exception like "list object has no attribute _sa_instance_state".

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

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

Solve this exception.

解决这个例外。

#3


1  

The most important thing while looking into this model is to understand the fact that this model has a one to many relationship, i.e. one Person has more than one address and we will store those addresses in a list in our case.

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

So, the Person class with its init will look something like this.

所以,带有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

So this Person class will be expecting an id, a name and a list that contains objects of type Address. I have kept that the default value to be an empty list.

所以这个Person类将期望一个id,一个名称和一个包含Address类型对象的列表。我保持默认值为空列表。

Hope it helps. :)

希望能帮助到你。 :)

#1


43  

You dont need to write a constructor, you can either treat the addresses property on a Person instance as a list:

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

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

Or you can pass a list of addresses to the Person constructor

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

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

In either case you can then access the addresses on your Person instance like so:

在任何一种情况下,您都可以访问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

#2


3  

In some cases there is have an Exception like "list object has no attribute _sa_instance_state".

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

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

Solve this exception.

解决这个例外。

#3


1  

The most important thing while looking into this model is to understand the fact that this model has a one to many relationship, i.e. one Person has more than one address and we will store those addresses in a list in our case.

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

So, the Person class with its init will look something like this.

所以,带有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

So this Person class will be expecting an id, a name and a list that contains objects of type Address. I have kept that the default value to be an empty list.

所以这个Person类将期望一个id,一个名称和一个包含Address类型对象的列表。我保持默认值为空列表。

Hope it helps. :)

希望能帮助到你。 :)