Inserting new records with one-to-many relationship in sqlalchemy

Solution 1:

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

a = Address(email='[email protected]')
p = Person(name='foo')
p.addresses.append(a)

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

a = Address(email='[email protected]')
p = Person(name='foo', addresses=[a])

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

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='[email protected]').count()) # 1

Solution 2:

I've gathered information here and elsewhere and found 3 ways to do so. In this model example (same as question):

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='[email protected]')
p = Person(name='foo', addresses=[a])

2.

p = Person(name='foo')
a = Address(email='[email protected]', person_id=p.id)

3.

a = Address(email='[email protected]')
p = Person(name='foo')
p.addresses.append(a)

Solution 3:

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.

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

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

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.

Hope it helps. :)