如何将一个 ponyorm 实体属性与其他几个实体相关联?
how to relate one ponyorm entity attribute with several other entities?
我开始使用现有数据库,其中 table A
的属性 foo
与多个 table、B.foo
相关和 C.foo
。我如何在 ponyorm 中建立这种关系?
数据库组织如下。
from pony import orm
db = orm.Database()
class POI(db.Entity):
'''Point of interest on a map'''
name = orm.PrimaryKey(str)
coordinateID = orm.Optional(('cartesian', 'polar')) # doesn't work ofc
class cartesian(db.Entity):
coordinateID = orm.Required(POI)
x = orm.Required(float)
y = orm.Required(float)
class polar(db.Entity):
coordinateID = orm.Required(POI)
r = orm.Required(float)
phi = orm.Required(float)
当然 x
,y
来自 cartesian
和 r
,phi
来自 polar
可以移动到 POI
,在我使用的数据库中,情况相同。但是 table 在利益相关者之间分配(在本例中为 cartesian
和 polar
),无论如何我都不会更改架构。我无法在架构中拆分 coordinateID
(但实际上 python class 具有不同的属性会很好)。
在 PonyORM 中不可能将一个属性与多个实体相关联,除非这些实体是从同一个基础实体继承的,那么你可以将基础实体指定为属性类型,并将任何继承的实体用作一个真正的类型。
如果您使用无法更改的现有模式,您可能无法使用继承并且需要指定原始 id 属性而不是关系:
from pony import orm
db = orm.Database()
class POI(db.Entity):
_table_ = "table_name"
name = orm.PrimaryKey(str)
coordinate_id = orm.Optional(int, column="coordinateID")
class Cartesian(db2.Entity):
_table_ = "cartesian"
id = orm.PrimaryKey(int, column="coordinateID")
x = orm.Required(float)
y = orm.Required(float)
class Polar(db2.Entity):
_table_ = "polar"
id = orm.PrimaryKey(int, column="coordinateID")
r = orm.Required(float)
phi = orm.Required(float)
然后你可以像这样执行查询:
left_join(poi for poi in POI
for c in Cartesian
for p in Polar
if poi.coordinate_id == c.id
and poi.coordinate_id = p.id
and <some additional conditions>)
请注意,同一查询中使用的所有实体都应来自同一数据库。如果实体属于两个不同的数据库,则不能在同一个查询中使用它们。并且需要发出单独的查询:
with db_session:
poi = POI.get(id=some_id)
coord = Cartesian.get(id=poi.coordinate_id)
if coord is None:
coord = Polar.get(id=poi.coordinate_id)
<do something with poi and coord>
但如果是 SQLite,您可以将一个数据库附加到另一个数据库,使它们显示为一个数据库。
我开始使用现有数据库,其中 table A
的属性 foo
与多个 table、B.foo
相关和 C.foo
。我如何在 ponyorm 中建立这种关系?
数据库组织如下。
from pony import orm
db = orm.Database()
class POI(db.Entity):
'''Point of interest on a map'''
name = orm.PrimaryKey(str)
coordinateID = orm.Optional(('cartesian', 'polar')) # doesn't work ofc
class cartesian(db.Entity):
coordinateID = orm.Required(POI)
x = orm.Required(float)
y = orm.Required(float)
class polar(db.Entity):
coordinateID = orm.Required(POI)
r = orm.Required(float)
phi = orm.Required(float)
当然 x
,y
来自 cartesian
和 r
,phi
来自 polar
可以移动到 POI
,在我使用的数据库中,情况相同。但是 table 在利益相关者之间分配(在本例中为 cartesian
和 polar
),无论如何我都不会更改架构。我无法在架构中拆分 coordinateID
(但实际上 python class 具有不同的属性会很好)。
在 PonyORM 中不可能将一个属性与多个实体相关联,除非这些实体是从同一个基础实体继承的,那么你可以将基础实体指定为属性类型,并将任何继承的实体用作一个真正的类型。
如果您使用无法更改的现有模式,您可能无法使用继承并且需要指定原始 id 属性而不是关系:
from pony import orm
db = orm.Database()
class POI(db.Entity):
_table_ = "table_name"
name = orm.PrimaryKey(str)
coordinate_id = orm.Optional(int, column="coordinateID")
class Cartesian(db2.Entity):
_table_ = "cartesian"
id = orm.PrimaryKey(int, column="coordinateID")
x = orm.Required(float)
y = orm.Required(float)
class Polar(db2.Entity):
_table_ = "polar"
id = orm.PrimaryKey(int, column="coordinateID")
r = orm.Required(float)
phi = orm.Required(float)
然后你可以像这样执行查询:
left_join(poi for poi in POI
for c in Cartesian
for p in Polar
if poi.coordinate_id == c.id
and poi.coordinate_id = p.id
and <some additional conditions>)
请注意,同一查询中使用的所有实体都应来自同一数据库。如果实体属于两个不同的数据库,则不能在同一个查询中使用它们。并且需要发出单独的查询:
with db_session:
poi = POI.get(id=some_id)
coord = Cartesian.get(id=poi.coordinate_id)
if coord is None:
coord = Polar.get(id=poi.coordinate_id)
<do something with poi and coord>
但如果是 SQLite,您可以将一个数据库附加到另一个数据库,使它们显示为一个数据库。