A Deduplication DB schema with sqlalchemy - 如何用 ORM 语义表示组?

发布于 2024-11-01 16:55:23 字数 713 浏览 11 评论 0原文

我正在尝试使用 mysql 创建实体重复数据删除模式的简单表示,并使用 sqlalchemy 进行编程访问。

我正在尝试实现一种特定的效果,我认为这是一种自引用查询,但我不确定:

本质上我有一个“实体”表(具有唯一的entity_id)和一个关联的实体对象, 然后是一个entity_groups表,为了简单起见,它有一个“group_id”和“entity_id”列,这样我就可以通过为该关系创建一行来向组“注册”一个实体。 该表也与 ORM 对象 - EntityGroup 关联。

问题是,如何获取 EntityGroup 对象引用组中的所有实体?

我希望我需要写一些类似的东西:

mapper(EntityGroup,entity_groups_table, 属性={ “实体”:关系( 实体, ....? ) },

我对细节有点模糊。基本上我需要entity_groups 中与对象表示的行具有相同group_id 的所有行。然后我需要实现 与这些行的entity_id 列关联的所有实体对象。这听起来像是可以通过 sqlalchemy 中更详细的 Query() 操作来实现,但我不确定如何将其与关系()构造结合起来(如果有的话 - 也许需要手动?)

任何帮助都会有用,我希望我说得很清楚并且切中要点

I'm trying to create a simple representation for an entity deduplication schema using mysql, and using sqlalchemy for programmatic access.

I'm trying to achieve a specific effect which I think is kind of a self-referential query but i'm not sure:

Essentially I have an 'entities' table (with unique entity_id) and an associated Entity object,
and then an entity_groups table which (for simplicity) has a 'group_id' and 'entity_id' columns, so that I 'register' an entity with a group by creating a row for that relation.
this table too is associated with an ORM object - EntityGroup.

Question is, how do i get the EntityGroup object reference all entities in the group?

I expect I need to write something like:

mapper(EntityGroup, entity_groups_table,
properties={
'entities': relationship(
Entity,
.... ?
)
},

and i'm alittle fuzzy on the details. Basically I need all the rows in entity_groups that have the same group_id as the row represented by the object. And then I need to materialize
all the Entity objects associated those rows' entity_id column. This sounds like something achievable by a more verbose Query() operation in sqlalchemy, but i'm not sure how to combine that with the relationship() construct (if at all - perhaps go manual? )

Any help will be useful, I hope I was clear and to the point

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄风 2024-11-08 16:55:23

您确实不应该使用查询来执行此操作,就好像您正确配置了关系一样,您将自动获得此结果。假设您仅使用 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>]

You really should not do it using a Query, as if you configure the relationships properly you will get this automatically. Assuming that you use entity_group table solely to store the relationship and nothing else, you should just configure many-to-many relationship as documented. Fully working example should help:

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

should produce something like:

group:  <Group: 1>  has  [<Entity: 1>]
group:  <Group: 2>  has  [<Entity: 1>, <Entity: 2>]
group:  <Group: 3>  has  [<Entity: 2>]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文