我正在尝试使用SQLAlchemy而且我没有SQL或SQLAlchemy经验。
我试图表示的数据不是简单的分层树。
有两种数据类型:记录和目标。它们是如此相关:
Base是SQLAlchemy的声明基础。
这是我尝试的代码,但是,我得到了CircularDependencyError
,但数据是循环的。
代码:
class Record(Model, Base):
""""""
__tablename__ = "records"
NAME = Column(String, primary_key = True)
TITLE = Column(Text)
COMPANY = Column(Text)
LOCATION = Column(Text)
DATE = Column(Text)
BLURB = Column(Text)
BULLET = Column(Text)
URL = Column(Text)
targets_id = Column(Text, ForeignKey("targets.NAME"))
targets = relationship("Target", back_populates = "records")
class Target(Model, Base):
""""""
__tablename__ = "targets"
NAME = Column(Text, primary_key = True)
MODULE = Column(Text)
URL = Column(Text)
JOB_URL = Column(Text)
COMPANY = Column(Text)
records_id = Column(String, ForeignKey("records.NAME"))
records = relationship("Record", back_populates = "targets")
我看过http://docs.sqlalchemy.org/en/rel_0_9/orm/relationships.html#many-to-many,但这看起来有点像黑客。是否有另一种方法可以在SQLAlchemy中表示这种方法来保留这种循环关系?
修改
一些示例数据:
RA:
NAME = "RA"
TITLE = ...
COMPANY = ...
LOCATION = ...
DATE = ...
BLURB = ...
BULLET = ...
URL = ...
TARGETS = [ TA, TD, ... ]
RB:
NAME = "RB"
TITLE = ...
COMPANY = ...
LOCATION = ...
DATE = ...
BLURB = ...
BULLET = ...
URL = ...
TARGETS = [ TB, TD, ... ]
TA:
NAME = "TA"
MODULE = ...
URL = ...
JOB_URL = ...
COMPANY = ...
RECORDS = [ RA, RB, ... ]
答案 0 :(得分:0)
作为RedBaron mentioned,SQL需要一个循环数据的中间表。
当我使用声明性基础时,我想要一个一致的解决方案;与documentation中提供的不同。
文档将中间表称为关联对象。
使用这些对象的语法在主观上是丑陋的,特别是在附加相关记录时(但这是SQL自身限制的结果)。所以我使用了Association Proxy;但是文档中的示例让新手感到困惑。
此解决方案基于this answer中找到的解决方案。
代码:
from sqlalchemy.ext.associationproxy import association_proxy
class Record(Model, Base):
""""""
__tablename__ = "records"
NAME = Column(String, primary_key = True)
TITLE = Column(Text)
COMPANY = Column(Text)
LOCATION = Column(Text)
DATE = Column(Text)
BLURB = Column(Text)
BULLET = Column(Text)
URL = Column(Text)
targets = association_proxy("target_records", "target", creator = lambda target: Target_Record(target = target))
def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self.NAME or "Unamed")
class Target(Model, Base):
""""""
__tablename__ = "targets"
NAME = Column(Text, primary_key = True)
MODULE = Column(Text)
URL = Column(Text)
JOB_URL = Column(Text)
COMPANY = Column(Text)
records = association_proxy("target_records", "record", creator = lambda record: Target_Record(record = record))
def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self.NAME or "Unamed")
class Target_Record(Model, Base):
__tablename__ = "target_records"
target_id = Column(Text , ForeignKey("targets.NAME"), primary_key = True)
record_id = Column(String, ForeignKey("records.NAME"), primary_key = True)
target = relationship(Target, backref = backref("target_records"))
record = relationship(Record, backref = backref("target_records"))