python - SQLAlchemy how to update children when old = [1, 2] new = [2, 3] -



python - SQLAlchemy how to update children when old = [1, 2] new = [2, 3] -

i have 2 models:

class person(model): id name skills = relationship(skill) class skill(model): id skill person_id

at beginning, example:

jack = person(name='jack') jack.skills = [skill(s) s in ['python', 'ruby']] jack.save()

then, 1 day, jack lost skill 'ruby' earned 'swift' skill ['python', 'swift'].

my current way of doing update is:

look existing skills, old = ['python', 'ruby'] get new list new = ['python', 'swift'] make old, new set(old), set(new) unchanged = old.intersection(new), skill not change i add together every skill in set(new - unchanged) i delete every skill in set(old-unchanged)

is there easier way this?

use collection_class=set on relationship treat set instead of list.

here's working illustration of how relate people skills. many-to-many relationship, instead of each skill beingness related 1 person_id, each skill can related many people through person_skill table. relationship collection set, , skill has __hash__ function create skills same name hash same.

from sqlalchemy import create_engine, column, integer, string, foreignkey, table sqlalchemy.ext.declarative import declarative_base sqlalchemy.orm import sessionmaker, relationship engine = create_engine('sqlite:///:memory:', echo=true) base of operations = declarative_base(bind=engine) session = sessionmaker(bind=engine) session = session() class person(base): __tablename__ = 'person' id = column(integer, primary_key=true) name = column(string, nullable=false, unique=true) # many-to-many relation, set skills = relationship('skill', 'person_skill', collection_class=set) class skill(base): __tablename__ = 'skill' id = column(integer, primary_key=true) name = column(string, nullable=false, unique=true) def __hash__(self): # set collection handle duplicate entries homecoming hash((self.__class__, self.name)) # many-to-many table, relate person skill person_skill = table( 'person_skill', base.metadata, column('person_id', integer, foreignkey(person.id), primary_key=true), column('skill_id', integer, foreignkey(skill.id), primary_key=true) ) # create tables base.metadata.create_all() # populate skills , people s1 = skill(name='python') s2 = skill(name='sqlalchemy') s3 = skill(name='questions') s4 = skill(name='ruby') p1 = person(name='davidism', skills={s1, s2, s4}) p2 = person(name='user2653947', skills={s3}) session.add_all([p1, p2]) session.commit() # alter skills on people p1.skills.discard(s4) p2.skills.add(s2) session.commit()

this not finish solution. instance plug in the unique object pattern demonstrated in answer create sure skills create never duplicated.

python sqlalchemy

Comments

Popular posts from this blog

model view controller - MVC Rails Planning -

ruby on rails - Devise Logout Error in RoR -

html - Submenu setup with jquery and effect 'fold' -