tldr; 在SQLAlchemy ORM Mapper类中 docs 提供了一个例子,说明如何在两个表之间创建关联表的多对多关系,像这样。
但是,我怎样才能创建一个有四个父表和一个子表的多对多关联?在下面的E/R图中,
keyword
、
solution
、
pattern
和
question
是父表,
data_lineage_lookup
是关联表,而
data_lineage
是子表。
背景信息。
我的数据库中有三个表来组织数据线元数据。第一个表,
data_lineage_lookup
,是一个关联表(多对多),其中的
id
列与其他四个表有外键关系。
question
,
solution
,
pattern
,和
keyword
。在
data_lineage_lookup
中,
id
列的每个id都是唯一的。每个这样的
id
都与一个
data_lineage_id
配对。
替换代码15】是
data_lineage
表的外键,该表持有关于数据来源的元数据,以json文档的形式保存在
json_body
列。
此外,
data_lineage
表中的每个json文档都有一个相应的
json_schema
(多对一的关系,许多文档共享相同的
json模式
)
-- association table I would like to recreate
CREATE TABLE IF NOT EXISTS data_lineage_lookup (
id TEXT NOT NULL,
data_lineage_id TEXT NOT NULL,
-- text id's of any kind can be used to look up data lineage
FOREIGN KEY (id) REFERENCES question (id) ON DELETE CASCADE,
FOREIGN KEY (id) REFERENCES solution (id) ON DELETE CASCADE,
FOREIGN KEY (id) REFERENCES pattern (id) ON DELETE CASCADE,
FOREIGN KEY (id) REFERENCES keyword (id) ON DELETE CASCADE,
FOREIGN KEY (data_lineage_id) REFERENCES data_lineage (id) ON DELETE CASCADE
CREATE TABLE IF NOT EXISTS data_lineage (
id TEXT NOT NULL PRIMARY KEY DEFAULT (lower(hex(randomblob(4)))),
json_schema_id INTEGER NOT NULL,
json_body TEXT NOT NULL,
date_found_timestamp INTEGER NOT NULL,
FOREIGN KEY (json_schema_id) REFERENCES json_schema (id) ON DELETE RESTRICT
CREATE TABLE IF NOT EXISTS json_schema (
id TEXT NOT NULL PRIMARY KEY DEFAULT (lower(hex(randomblob(4)))),
title TEXT NOT NULL,
body TEXT NOT NULL,
date_added_timestamp INTEGER NOT NULL
The question:根据有关文件ORM映射器类中的多对多关系下面的例子用来说明如何使用关联表和relationship()
列来建立多对多的关系,但这里的关联表有两列--它所关联的每个表都有一列,所以relationship()
的使用是直接的。
association_table = Table('association', Base.metadata,
Column('left_id', ForeignKey('left.id')),
Column('right_id', ForeignKey('right.id'))
class Parent(Base):
__tablename__ = 'left'
id = Column(Integer, primary_key=True)
children = relationship("Child",
secondary=association_table)
class Child(Base):
__tablename__ = 'right'
id = Column(Integer, primary_key=True)
我已经在SQLAlchemy中声明了下面的映射器类,但我如何配置data_lineage_lookup.id
列,使其作为一个单一的外键列,映射到4个不同的表。替换代码3】、solution
、pattern
和keyword
,通过JsonSchema
中的relationship()
来实现。ORM Mapper类?
Document Metadata Schema
@declarative_mixin
class DocumentMetadata:
id = Column(Text, nullable=False, primary_key=True, default=text('(lower(hex(randomblob(4))))'), server_default=text('(lower(hex(randomblob(4))))'))
body = Column(JSON, nullable=False) # TODO: check datatype after loading data with `select typeof(col) from table;`
date_added = Column(DATETIME, nullable=False)
def __repr__(self):
return f"<{self.__class__.__name__}{self.__dict__}>"
@declared_attr
def __tablename__(cls):
return re.sub(r'(?<!^)(?=[A-Z])', '_', cls.__name__).lower()
data_lineage_lookup = Table(
'data_lineage_lookup',
Base.metadata,
Column('id',
ForeignKey('question.id', ondelete="CASCADE"),
ForeignKey('solution.id', ondelete="CASCADE"),
ForeignKey('pattern.id', ondelete="CASCADE"),
ForeignKey('keyword.id', ondelete="CASCADE")
Column('data_lineage_id', ForeignKey('data_lineage.id', ondelete="CASCADE"))
class JsonSchema(Base, DocumentMetadata):
title = Column(Text, nullable=False)
class DataLineage(Base, DocumentMetadata):
json_schema_id = Column(Text, ForeignKey('json_schema.id', ondelete='RESTRICT'), nullable=False)