如何将一个ponyorm实体属性与其他几个实体相关联?

时间:2019-04-12 17:57:00

标签: python ponyorm

我开始使用现有数据库,其中表from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from math import sqrt class Point(QGraphicsItem): def __init__(self, x, y): super(Point, self).__init__() self.setFlag(QGraphicsItem.ItemIsSelectable, True) self.rectF = QRectF(0, 0, 30, 30) self.x=x self.y=y self._brush = QBrush(Qt.black) def setBrush(self, brush): self._brush = brush self.update() def boundingRect(self): return self.rectF def paint(self, painter=None, style=None, widget=None): painter.fillRect(self.rectF, self._brush) def hoverMoveEvent(self, event): point = event.pos().toPoint() print(point) QGraphicsItem.hoverMoveEvent(self, event) class Viewer(QGraphicsView): photoClicked = pyqtSignal(QPoint) rectChanged = pyqtSignal(QRect) def __init__(self, parent): super(Viewer, self).__init__(parent) self.rubberBand = QRubberBand(QRubberBand.Rectangle, self) self.setMouseTracking(True) self.origin = QPoint() self.changeRubberBand = False self._zoom = 0 self._empty = True self._scene = QGraphicsScene(self) self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) self.setResizeAnchor(QGraphicsView.AnchorUnderMouse) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setFrameShape(QFrame.NoFrame) self.area = float() self.setPoints() def setItems(self): self.data = {'x': [-2414943.8686, -2417160.6592, -2417160.6592, -2417856.1783, -2417054.7618, -2416009.9966, -2416012.5232, -2418160.8952, -2418160.8952, -2416012.5232, -2417094.7694, -2417094.7694], 'y': [10454269.7008, 10454147.2672, 10454147.2672, 10453285.2456, 10452556.8132, 10453240.2808, 10455255.8752, 10455183.1912, 10455183.1912, 10455255.8752, 10456212.5959, 10456212.5959]} maxX = max(self.data['x']) minX = min(self.data['x']) maxY = max(self.data['y']) minY = min(self.data['y']) distance = sqrt((maxX-minX)**2+(maxY-minY)**2) self.area = QRectF(minX, minY, distance, distance) for i,x in enumerate(self.data['x']): x = self.data['x'][i] y = self.data['y'][i] p = Point(x,y) p.setPos(x,y) self._scene.addItem(p) self.setScene(self._scene) def fitInView(self, scale=True): rect = QRectF(self.area) if not rect.isNull(): self.setSceneRect(rect) unity = self.transform().mapRect(QRectF(0, 0, 1, 1)) self.scale(1 / unity.width(), 1 / unity.height()) viewrect = self.viewport().rect() scenerect = self.transform().mapRect(rect) factor = min(viewrect.width() / scenerect.width(), viewrect.height() / scenerect.height()) self.scale(factor, factor) self._zoom = 0 def setPoints(self): self._zoom = 0 self.setItems() self.setDragMode(True) self.fitInView() def wheelEvent(self, event): if event.angleDelta().y() > 0: factor = 1.25 self._zoom += 1 else: factor = 0.8 self._zoom -= 1 if self._zoom > 0: self.scale(factor, factor) elif self._zoom == 0: self.fitInView() else: self._zoom = 0 def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.origin = event.pos() self.rubberBand.setGeometry(QRect(self.origin, QSize())) self.rectChanged.emit(self.rubberBand.geometry()) self.rubberBand.show() self.changeRubberBand = True self.mousePressEvent(event) elif event.button() == Qt.MidButton: self.viewport().setCursor(Qt.ClosedHandCursor) self.original_event = event handmade_event = QMouseEvent(QEvent.MouseButtonPress,QPointF(event.pos()),Qt.LeftButton,event.buttons(),Qt.KeyboardModifiers()) self.mousePressEvent(handmade_event) super(Viewer, self).mousePressEvent(event) def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self.changeRubberBand = False self.mouseReleaseEvent(event) elif event.button() == Qt.MidButton: self.viewport().setCursor(Qt.OpenHandCursor) handmade_event = QMouseEvent(QEvent.MouseButtonRelease,QPointF(event.pos()),Qt.LeftButton,event.buttons(),Qt.KeyboardModifiers()) self.mouseReleaseEvent(handmade_event) super(Viewer, self).mouseReleaseEvent(event) def mouseMoveEvent(self, event): if self.changeRubberBand: self.rubberBand.setGeometry(QRect(self.origin, event.pos()).normalized()) self.rectChanged.emit(self.rubberBand.geometry()) self.mouseMoveEvent(event) super(Viewer, self).mouseMoveEvent(event) class Window(QWidget): def __init__(self): super(Window, self).__init__() self.viewer = Viewer(self) self.btnLoad = QToolButton(self) self.btnLoad.setText('Load Points') self.btnLoad.clicked.connect(self.loadPoints) VBlayout = QVBoxLayout(self) VBlayout.addWidget(self.viewer) HBlayout = QHBoxLayout() HBlayout.setAlignment(Qt.AlignLeft) HBlayout.addWidget(self.btnLoad) VBlayout.addLayout(HBlayout) def loadPoints(self): self.viewer.setPoints() if __name__ == '__main__': import sys app = QApplication(sys.argv) window = Window() window.setGeometry(500, 300, 800, 600) window.show() sys.exit(app.exec_()) 的属性foo与另一个表AB.foo有关。如何在ponyorm中建立这种关系?

数据库的组织方式如下。

C.foo

当然可以将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) 中的xycartesian中的r,p hi移到polar ,并且在我使用的数据库中,情况相同。但是这些表是在各涉众之间划分的(在此示例中为POIcartesian),我还是无法更改架构。我无法在架构中拆分polar(但是拥有python类的不同属性实际上会很好。)

1 个答案:

答案 0 :(得分:1)

在PonyORM中无法为多个实体关联一个属性,除非这些实体是从同一基础实体继承的,然后您可以将基础实体指定为属性类型,并使用任何继承的实体作为真实实体类型。

如果使用无法更改的现有架构,则可能无法使用继承,需要指定原始id属性而不是关系:

Public Sub ReadXml()
    ' XML FILE:
    ' <A>
    '     <B>sometext</B>
    ' </A>
    Dim n As New MSXML2.DOMDocument60
    Dim n1 As MSXML2.IXMLDOMNode
    Const NomeFile = "C:\file.xml"
    n.async = False
    n.validateOnParse = False
    If n.Load(NomeFile) Then
        Set n1 = n.selectSingleNode("A/B")
        Debug.Print n1.Text ' <===  error
    End If
End Sub

然后您可以执行以下查询:

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>)

但是,例如,对于SQLite,您可以将一个数据库附加到另一个数据库,以使它们显示为单个数据库。