Заполнение отношения SQLAlchemy "многие ко многим" с использованием идентификаторов вместо объектов
ситуация:
Итак, у меня есть основное отношение "многие ко многим" в SQLAlchemy с использованием ассоциации таблице.
Например, человек может присутствовать на многих вечеринках, а на вечеринке может быть много гостей:
class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = db.Column(db.String(50))
class SexyParty(Base):
__tablename__ = 'sexy_party'
id = Column(Integer, primary_key=True)
guests = relationship('Person', secondary='guest_association',
lazy='dynamic', backref='parties')
guest_association = Table(
'guest_association',
Column('user_id', Integer(), ForeignKey('person.id')),
Column('sexyparty.id', Integer(), ForeignKey('sexyparty.id'))
)
обычно, если бы я хотел добавить список гостей на вечеринку, я бы сделал что-то вроде этого:
my_guests = [prince, olivia, brittany, me]
my_party.guests = guests
db.session.commit()
...где принц, Оливия и Бриттани все <Person>
экземпляры, и my_party является <SexyParty>
экземпляра.
у меня вопрос:
Я хотел бы добавить гостей на вечеринку, используя идентификатор человека, а не экземпляры. Например:
guest_ids = [1, 2, 3, 5]
my_party.guests = guest_ids # <-- This fails, because guest_ids
# are not <Person> instances
Я всегда мог загружать экземпляры из баз данных, но это повлечет за собой ненужный запрос БД, чтобы установить простые отношения "многие ко многим".
как бы я идти о настройке .guests
атрибут, используя список person_id?
Там должен быть простой способ сделать это с таблица ассоциаций в конечном счете представляет отношение "многие ко многим", используя ID в любом случае...
заранее спасибо, надеюсь вопрос понятен.
1 ответов
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = Column(String(50))
class SexyParty(Base):
__tablename__ = 'sexy_party'
id = Column(Integer, primary_key=True)
guests = relationship('Person', secondary='guest_association',
lazy='dynamic', backref='parties')
guest_association = Table(
'guest_association', Base.metadata,
Column('user_id', Integer(), ForeignKey('person.id'), primary_key=True),
Column('sexyparty_id', Integer(), ForeignKey('sexy_party.id'), primary_key=True)
)
e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
sess = Session(e)
p1 = Person(id=1, name='p1')
p2 = Person(id=2, name='p2')
p3 = Person(id=3, name='p3')
p4 = Person(id=4, name='p4')
sp1 = SexyParty(id=1)
sess.add_all([sp1, p1, p2, p3, p4])
sess.commit()
# method one. use insert()
sess.execute(guest_association.insert().values([(1, 1), (2, 1)]))
# method two. map, optional association proxy
from sqlalchemy.ext.associationproxy import association_proxy
class GuestAssociation(Base):
__table__ = guest_association
party = relationship("SexyParty", backref="association_recs")
SexyParty.association_ids = association_proxy(
"association_recs", "user_id",
creator=lambda uid: GuestAssociation(user_id=uid))
sp1.association_ids.extend([3, 4])
sess.commit()