web-dev-qa-db-fra.com

Insertion de nouveaux enregistrements avec une relation un-à-plusieurs dans sqlalchemy

Je suis le tutoriel flask-sqlalchemy sur déclaration de modèles concernant la relation un-à-plusieurs. L'exemple de code est le suivant:

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

Maintenant, je me demande comment insérer de nouveaux enregistrements dans DB en utilisant un tel modèle. Je suppose que j'ai besoin d'un constructeur init , mais j'ai du mal à comprendre comment il doit être implémenté et utilisé. Le problème principal pour moi ici est que la personne dépend de l'adresse et que l'adresse possède une clé étrangère pour la personne, elle doit donc connaître la personne à l'avance.

Veuillez m'aider à comprendre comment cela doit être effectué.

Merci d'avance.

34
wanderlust

Vous n'avez pas besoin d'écrire un constructeur, vous pouvez soit traiter la propriété addresses sur une instance Person comme une liste:

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

Ou vous pouvez passer une liste d'adresses au constructeur Person

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

Dans les deux cas, vous pouvez alors accéder aux adresses de votre instance Person comme ceci:

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
62
DazWorrall

Dans certains cas, il existe une exception telle que "l'objet de liste n'a pas d'attribut _sa_instance_state".

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

Résolvez cette exception.

3
cyberra

La chose la plus importante en examinant ce modèle est de comprendre le fait que ce modèle a une relation un à plusieurs, c'est-à-dire qu'une personne a plus d'une adresse et nous stockerons ces adresses dans une liste dans notre cas.

Ainsi, la classe Person avec son init ressemblera à ceci.

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

Cette classe Person attendra donc un identifiant, un nom et une liste contenant des objets de type Adresse. J'ai gardé que la valeur par défaut était une liste vide.

J'espère que cela aide. :)

1
padfoot27