【问题标题】:populate connection tables with sqlalchemy ORM for a complex schema使用 sqlalchemy ORM 为复杂模式填充连接表
【发布时间】:2021-11-04 14:19:52
【问题描述】:

我正在尝试将复杂的监管分类数据集导入新数据库。复杂性来自于将不同种类的分类器分配给相同的分类对象。有分层(一对多)“类别”和非分层(多对多)“属性”,每个“属性”都有指定的值范围。问题在于填充数据。由于每个最低“类别”的非分层“属性”都不相同,因此仅标记secondary 关系属性和a.append(b) 不会为连接表生成所需的输入。 JSON 将是一种很好的格式,但由于记录数量众多,它不可行。我正在寻找保留和填充下面提供的架构的最佳方式。这是一个简化的示例:

Supercat  Category  Subcategory Attr.Type Attribute  Attr.Value

Vertebrae Mammals   Cats        Color     Hair Color Blue
                                          Hair Color Black
                                          Eye Color  Blue
                                          Eye Color  Green
                                Magic     Yes/No     Maybe
                                Legs      Count      4
                                Habitat   Land/Sea   Land
                    Dogs        Color     Hair Color Brown
                                          Hair Color Black
                                          Eye Color  Blue
                                          Eye Color  Green
                                Magic     Yes/No     No
                                Legs      Count      4
                                Tailwags  Happy      Yes
                                          Unhappy    No
                                Habitat   Land/Sea   Land
                    Whales      Color     Skin Color Blue
                                          Skin Color Grey
                                Habitat   Land/Sea   Sea
                    Unicorns    Color     Hair Color Rainbow
                                Magic     Yes/No     Yes
                                Habitat   Land/Sea   Unknown
                                Legs      Count      4
                                          Hooves     Yes
          Fish      Sharks      Color     Skin Color White
                                          Skin Color Grey
                                Magic     Yes/No     No
                                Habitat   Land/Sea   Sea
                    Goldfish    Color     Scales     Gold
                                Habitat   Land/Sea   Sea

这是此设置的架构的 SQLAlchemy ORM 表示:

#connection tables:
attribute_type_attributes = db.Table('attribute_type_attributes',
    db.Column('type_id', db.ForeignKey('attribute_types.id'), ...),
    db.Column('attribute_id', db.ForeignKey('attributes.id'), ...)
)

attribute_values_attributes = db.Table('attribute_type_attributes',
    db.Column('type_id', db.ForeignKey('attribute_types.id'), ...),
    db.Column('value_id', db.ForeignKey('attribute_values.id'), ...)
)

subcategory_attribute_types = db.Table('subcategory_attribute_types',
    db.Column('type_id', db.ForeignKey('attribute_types.id'), ...),
    db.Column('subcat_id', db.ForeignKey('subcats.id'), ...)
)

subcategory_attributes = db.Table('subcategory_attributes',
    db.Column('type_id', db.ForeignKey('attributes.id'), ...),
    db.Column('subcat_id', db.ForeignKey('subcats.id'), ...)
)

subcategory_attribute_values = db.Table('subcategory_attribute_values',
    db.Column('type_id', db.ForeignKey('attribute_values.id'), ...),
    db.Column('subcat_id', db.ForeignKey('subcats.id'), ...)
)
#models:
class Supercat(db.Model):
    id = db.Column(...)
    name = db.Column(...)

class Cat(db.Model):
    id = db.Column(...)
    supercat_id = db.Column(..., db.ForeignKey('supercats.id'), ...)
    name = db.Column(...)

class Subcat(db.Model):
    id = db.model(...)
    cat_id = db.Column(..., db.ForeignKey('cats.id'), ...)
    name = db.Column(...)

class Attribute_type(db.Model):
    __tablename__ = 'attribute_types'
    id = db.Column(...)
    name = db.Column(...)

class Attribute(db.Model):
    __tablename__ = 'attributes'
    id = db.Column(...)
    name = db.Column(...)

class Attribute_value(db.Model):
    __tablename__ = 'attribute_values'
    id = db.Column(...)
    name = db.Column(...)

同样,不同的分层“类别”具有不同的非分层“属性”,它们与不同的值集相关。我不能拥有与错误“子类别”相关的非分层“属性”或其值,因为数据不是我可以更改的。

有什么想法吗?

【问题讨论】:

  • 在您的表格列表中有对 attribute_types.idattributes.id 的引用,但这些表格不包括在内。可以包含整个架构吗?
  • 我现在在现有模式中显示了__tablename__ 类属性。给定类名,这些是隐含的。大多数其他细节仍然被省略,以便专注于通用解决方案。
  • 抱歉,我不熟悉 SQLAlchemy,我希望看到第一部分中指定的所有相关表/列(例如 #connection tables:)和/或只是底层 SQL DDL。

标签: python postgresql sqlalchemy many-to-many flask-sqlalchemy


【解决方案1】:

要存储类别层次结构,您可以使用当前拥有的 3 个表(super-cat、cat、sub-cat)或单个表(带有 parent_category_id 的类别)。我可能会使用一个表,但单独的表似乎也很好。

然后有一个表来存储各种属性(例如“头发颜色”) attributes 表与 idattribute_typename 列。您可以将attribute_type 存储为字符串(例如Color)或作为对存储名称Colorattribute_types 表的引用。

最后,为了存储每个子类别的属性值,我将有一个表(例如subcategory_attributes),它引用子类别表和属性表并存储value(例如“蓝色”) .您也可以将values 提取到他们自己的表中,如果您想进一步规范化数据/如果有意义的话,只需引用它们即可。

这里有一些描述架构的可怕 ascii 艺术。

[ super-categories ]      [  attribute_types (name:Color)    ]
        ^                                    ^
        |                                    |
[   categories     ]      [     attributes (name:Hair color) ]
        ^                                    ^
        |                                    |
[  subcategories   ]  <-- [ subcategory_attributes (value:Blue) ]  

也许我遗漏了一些东西,但我认为我遗漏了将一个或多个属性值(具有特定属性类型等)与特定子类别相关联的困难。

【讨论】:

  • 谢谢!这是我的第一个模式,包括规范化的attribute_values 关系。但是,在这种情况下,将attribute 关系和attribute_type 关系与subcategories 关联时遇到了问题。我看不到填充这些关系之间的连接表的方式,我需要它们来允许用户识别与subcategory 相关的attribute_typeattribute。需要注意的是,attributes 之间的值不是唯一的,因此架构中的右下角关系是不够的。另一种一对多的值层次结构太复杂了
  • 一旦我识别出attributeattribute_type 不是隐含的吗?例如如果我选择Hair Color 类型不总是Color 吗?为什么我需要两者都选?
  • “我看不到填充这些关系之间的连接表的方式”是 SQLAlchemy 的限制吗?您能否详细说明您在填充连接表时遇到的挑战?
  • HairColor attributetype 在这种情况下始终是Color,但也可以是Hair,并且有一个YesNo attribute 属于大量types。因此,用户选择必须从type 级别开始。至于填充连接表的挑战,如果不创建一个巨大的 JSON 并循环遍历每个级别以将连接元组分配给适当的关系,我无法找到一种插入数据的方法。也许我需要接受这种可能性,然后就这样做,但我希望有人能启发我了解我目前无法掌握的 sqlalchemy 能力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 2022-01-24
  • 2023-03-05
  • 2021-08-30
  • 1970-01-01
  • 1970-01-01
  • 2015-02-10
相关资源
最近更新 更多