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 [email protected].
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()