Схема дедупликации БД с sqlalchemy - Как представить группу с семантикой ORM? - PullRequest
0 голосов
/ 18 апреля 2011

Я пытаюсь создать простое представление для схемы дедупликации сущностей, используя mysql и используя sqlalchemy для программного доступа.

Я пытаюсь добиться определенного эффекта, который, на мой взгляд, является чем-то вроде себязапрос, но я не уверен:

По сути, у меня есть таблица «entity» (с уникальным entity_id) и связанный объект Entity, а затем таблица entity_groups, которая (для простоты) имеет «group_id»и столбцы «entity_id», чтобы я «регистрировал» сущность в группе, создавая строку для этого отношения.эта таблица также связана с объектом ORM - EntityGroup.

Вопрос в том, как получить объект EntityGroup, ссылающийся на все сущности в группе?

Я ожидаю, что мне нужно написать что-то вроде:

mapper (EntityGroup, entity_groups_table, properties = {'entity': Relationship (Entity, ....?)},

и я немного нечеткий в деталях. В основном мне нужны все строки в entity_groups, которые имеют тот же group_id, что и строка, представленная объектом. И затем мне нужно материализовать все объекты Entity, связанные с этими столбцами entity_id.Это звучит как что-то достижимое более многословной операцией Query () в sqlalchemy, но я не уверен, как объединить это с конструкцией Relations () (если вообще - возможно, пойти вручную?)

Любая помощьбудет полезен, надеюсь, мне было понятно и по делу

1 Ответ

0 голосов
/ 19 апреля 2011

Вы действительно не должны делать это, используя Query, так как, если вы правильно настроите отношения, вы получите это автоматически.Предполагая, что вы используете таблицу entity_group исключительно для хранения отношений и ничего больше, вы должны просто настроить отношение многие-ко-многим , как описано.Полностью рабочий пример должен помочь:

from sqlalchemy import create_engine, Column, Integer, String, MetaData, ForeignKey, Table
from sqlalchemy.orm import relationship, mapper, scoped_session, sessionmaker, backref
from sqlalchemy.ext.associationproxy import association_proxy

# Configure test DB
engine = create_engine(u'sqlite:///:memory:', echo=False)
session = scoped_session(sessionmaker(bind=engine, autoflush=False))
metadata = MetaData()

# tables
entities_table = Table('entities', metadata,
    Column('entity_id', Integer, primary_key=True),
)

groups_table = Table('groups', metadata,
    Column('group_id', Integer, primary_key=True),
)

entity_groups_table = Table('entity_groups', metadata,
    Column('entity_id', Integer, ForeignKey('entities.entity_id'), primary_key=True),
    Column('group_id', Integer, ForeignKey('groups.group_id'), primary_key=True),
)

# object model
class Group(object):
    def __repr__(self): return "<Group: %d>" % (self.group_id,)
class Entity(object):
    def __repr__(self): return "<Entity: %d>" % (self.entity_id,)

# mappers
mapper(Group, groups_table)
mapper(Entity, entities_table, 
       properties={'groups': relationship(Group, secondary=entity_groups_table, backref='entities')},
       )

# create db schema
metadata.create_all(engine)

# == TESTS
# create entities
e1 = Entity()
e2 = Entity()
g1 = Group()
g2 = Group()
g3 = Group()
g1.entities.append(e1)
g2.entities.append(e2)
g3.entities.append(e1)
g3.entities.append(e2)
session.add(e1)
session.add(e2)
session.commit()

# query...
session.expunge_all()

# check Peter
for g in session.query(Group).all():
    print "group: ", g, " has ", g.entities

должен выдать что-то вроде:

group:  <Group: 1>  has  [<Entity: 1>]
group:  <Group: 2>  has  [<Entity: 1>, <Entity: 2>]
group:  <Group: 3>  has  [<Entity: 2>]
...