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

Reply via email to