我有三个表:UserTypeMapper、User和SystemAdmin。在我的get_user
方法中,取决于UserTypeMapper.is_管理行,然后查询User或SystemAdmin表。user_id
行与User和SystemAdmin表中的主键id
相关。在
class UserTypeMapper(Base):
__tablename__ = 'user_type_mapper'
id = Column(BigInteger, primary_key=True)
is_admin = Column(Boolean, default=False)
user_id = Column(BigInteger, nullable=False)
class SystemAdmin(Base):
__tablename__ = 'system_admin'
id = Column(BigInteger, primary_key=True)
name = Column(Unicode)
email = Column(Unicode)
class User(Base):
__tablename__ = 'user'
id = Column(BigInteger, primary_key=True)
name = Column(Unicode)
email = Column(Unicode)
我希望能够从一个查询中获得任何用户(系统管理员或普通用户),因此我在User
或{is_admin
行执行联接。例如:
以及
DBSession.query(UserTypeMapper, User).join(User, UserTypeMapper.user_id==User.id).first()
这样做很好;但是,我想访问这些,如下所示:
>>> my_admin_obj.is_admin
True
>>> my_admin_obj.name
Bob Smith
与
>>> my_user_obj.is_admin
False
>>> my_user_obj.name
Bob Stevens
目前,我必须指定:my_user_obj.UserTypeMapper.is_admin
和my_user_obj.User.name
。根据我所读到的,我需要映射表,这样就不需要指定属性属于哪个表。我的问题是,如果我有两个潜在的表,例如name
属性可能来自这些表,我不知道如何指定它。在
这是我所指的示例:Mapping a Class against Multiple Tables
我怎样才能做到这一点?谢谢您。在
您已经发现了为什么“dual purpose foreign key”是antipattern。在
与此相关的一个问题您还没有完全指出;没有办法使用外键约束来强制使数据处于有效状态。您需要确保UserTypeMapper中的每一行都有一个something,但是这个'something'不是任何一个表。从形式上来说,你想要一个功能上的依赖
但是大多数sql数据库不允许您编写一个外键约束来表达这一点。在
它看起来很复杂,因为它很复杂。在
相反,让我们考虑一下我们真正想说的话:“每个
system_admin
应该是user
;或者在sql中,可以这样写:
或者,在sqlalchemy声明式样式中
^{pr2}$这个模式允许我们提出什么样的问题?在
我希望你能明白为什么上面的设计比你在问题中描述的设计更合适;但是如果你没有选择的机会(而且只有在这种情况下,如果你仍然觉得你得到的更好,请改进你的问题),你仍然可以将数据填充到一个python对象中,这将是非常困难的工作,通过提供一个替代映射到表;特别是一个遵循第一个方程中的粗略结构的映射。在
我们需要提到UserTypeMapper两次,一次针对联合体的每一方,为此,我们需要给出别名。在
对于联合体,将每个别名连接到适当的表中:由于}具有相同顺序的相同列,我们不需要详细描述它们,但是如果它们完全不同,我们需要通过显式地提到每一列来使它们“联合兼容”;这是一个练习。在
SystemAdmin
和{然后我们把他们连在一起。。。在
虽然理论上可以将这些都打包成一个python类,看起来有点像标准的sqlalchemy orm东西,但我肯定会而不是这样做。使用非表映射,特别是当它们不仅仅是简单的连接(这是一个联合)时,要实现零回报,需要做大量的工作。在
相关问题 更多 >
编程相关推荐