Sqlalchemy 定义一个仅在某些情况下为真的关系()
我使用的数据库模式的关系并不总是正确的,我不知道如何用sqlalchemy的ORM来描述它 此数据库中的所有主键都存储为blob类型,是16字节的二进制字符串 我有一个名为Sqlalchemy 定义一个仅在某些情况下为真的关系(),sqlalchemy,Sqlalchemy,我使用的数据库模式的关系并不总是正确的,我不知道如何用sqlalchemy的ORM来描述它 此数据库中的所有主键都存储为blob类型,是16字节的二进制字符串 我有一个名为属性的表,这个表有一个名为数据类型的列。有许多内置的数据类型s未在数据库中明确定义。因此,可能00的data\u type表示它是一个字符串,01表示它是一个浮点值,等等(这些是十六进制值)。内置数据类型的最大值为12(十进制为18) 但是,对于属性中的某些行,该行中存储的属性值必须存在于预定义的值列表中。在这种情况下,dat
属性
的表,这个表有一个名为数据类型
的列。有许多内置的数据类型
s未在数据库中明确定义。因此,可能00的data\u type
表示它是一个字符串,01
表示它是一个浮点值,等等(这些是十六进制值)。内置数据类型的最大值为12
(十进制为18)
但是,对于属性
中的某些行,该行中存储的属性值必须存在于预定义的值列表中。在这种情况下,data\u type
引用lookup.lookup\u id
。然后可以从查找中检索属性的实际数据类型。data\u type
我希望能够调用Attribue.data\u type
并返回“string”或“number”。显然,我需要在某个地方定义{0x00:'string',0x01:'number'}
映射,但是如果属性.data\u type
的值大于18,我如何告诉sqlalchemy我想要查找.data\u type
lookup
。你说你“需要在某个地方定义…映射”,而一个表就是一个很好的地方属性。唯一的问题是你不能对它进行查询。您需要重新指定列数据类型
,以便它映射到\u数据类型
:
data_type_dict = {0x00: 'string',
0x01: 'number,
...}
class Attribute(Base):
__tablename__ = 'attribute'
_data_type = Column('data_type')
...
@property
def data_type(self):
dt = data_type_dict.get(self._data_type, None)
if dt is None:
s = Session.object_session(self)
lookup = s.query(Lookup).filter_by(id=self._data_type).one()
dt = lookup.data_type
return dt
session.query(Attribute).filter\u by(data\u type='string')
,则需要将数据类型映射到数据库可以处理的对象,即SQL语句。您可以在原始SQL中作为大小写
表达式执行此操作:
from sqlalchemy.sql.expression import select, case
class Attribute(Base):
...
data_type = column_property(select([attribute, lookup])\
.where(attribute.data_type==lookup.lookup_id)\
.where(case([(attribute.data_type==0x00, 'string'),
(attribute.data_type==0x01, 'number'),
...],
else_=lookup.data_type))
我不能百分之百肯定最后一部分会起作用;您可能需要显式地连接表属性
和查找
,以指定它是外部连接,尽管我认为默认情况下SQLAlchemy会这样做。这种方法的缺点是,您总是试图加入表查找
,尽管要使用SQL进行查询,您必须这样做class Attribute(Base):
__tablename__ = 'attribute'
_data_type = Column('data_type')
_lookup = column_property(attribute.data_type > 18)
__mapper_args__ = {'polymorphic_on': _lookup}
class FixedAttribute(Attribute):
__mapper_args__ = {'polymorphic_identity': 0}
data_type = column_property(select([attribute.data_type])\
.where(case([(attribute.data_type==0x00, 'string'),
(attribute.data_type==0x01, 'number'),
...])))
class LookupAttribute(Attribute):
__mapper_args__ = {'polymorphic_identity': 1}
data_type = column_property(select([lookup.data_type],
whereclause=attribute.data_type==lookup.lookup_id))
您可能必须用显式的属性替换'polymorphic\u on':\u lookup
。数据类型>18
,具体取决于该列属性的绑定时间