Hello, I’m noodling through the Composite Column Types <https://docs.sqlalchemy.org/en/14/orm/composites.html> examples, and can’t make it work. Based on the code on that page I put together a minimal, reproducible example <https://stackoverflow.com/help/minimal-reproducible-example> (attached) which fails with
*Traceback (most recent call last): File "/path/to/test.py", line 75, in <module> assert v1.start > v2.startTypeError: '>' not supported between instances of 'Point' and 'Point'* Why is that? What am I missing? I expected to see SQL generated that implements the “greater than” between two *Point* instances (or perhaps *Vertex* instance, not sure, probably not). Much thanks! Jens -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/149c1ae1-94af-4a4e-884c-171f72eb010bn%40googlegroups.com.
import logging from sqlalchemy import Column, Integer, engine_from_config, sql from sqlalchemy.orm import composite, declarative_base, sessionmaker from sqlalchemy.orm.properties import CompositeProperty logging.basicConfig(level=logging.DEBUG, force=True) logging.getLogger("sqlalchemy.engine").setLevel(logging.DEBUG) class PointComparator(CompositeProperty.Comparator): def __gt__(self, other): """redefine the 'greater than' operation""" return sql.and_( *[ a > b for a, b in zip( self.__clause_element__().clauses, other.__composite_values__(), ) ] ) class Point: def __init__(self, x, y): self.x = x self.y = y def __composite_values__(self): return self.x, self.y def __repr__(self): return f"Point(x={self.x!r}, y={self.y!r})" def __eq__(self, other): return isinstance(other, Point) and other.x == self.x and other.y == self.y def __ne__(self, other): return not self.__eq__(other) Base = declarative_base() class Vertex(Base): __tablename__ = "vertices" id = Column(Integer, primary_key=True) x1 = Column(Integer) y1 = Column(Integer) x2 = Column(Integer) y2 = Column(Integer) start = composite(Point, x1, y1, comparator_factory=PointComparator) end = composite(Point, x2, y2, comparator_factory=PointComparator) engine = engine_from_config({"sqlalchemy.url": "postgresql+psycopg2://postgres:postgres@localhost/testdb"}) Base.metadata.drop_all(engine) Base.metadata.create_all(engine) connection = engine.connect() make_session = sessionmaker(bind=connection) dbsession = make_session() v1 = Vertex(start=Point(1, 2), end=Point(3, 4)) dbsession.add(v1) v2 = Vertex(start=Point(4, 4), end=Point(9, 9)) dbsession.add(v2) dbsession.flush() # assert v1 > v2 assert v1.start > v2.start dbsession.commit() connection.close() engine.dispose()