For reference I have attached a complete test case including a copy of the GUID code from the documentation.
On May 6, 2013, at 23:22, Wichert Akkerman <wich...@wiggy.net> wrote: > I was looking at using a UUID as primary key for a table. Using the > backend-agnostic GUID type from > http://docs.sqlalchemy.org/en/rel_0_8/core/types.html#backend-agnostic-guid-type > I get strange behaviour though. I whipped up a simple test case: > > > class Data(BaseObject): > __tablename__ = 'data' > uuid = Column(GUID(), primary_key=True) > > > metadata.create_all() > session = sessionmaker(autocommit=False)() > > uuid = 'ac4daeff-3af3-4b83-b8c7-3aa34e34151c' > obj = Data(uuid=uuid) > session.add(obj) > assert session.query(Data).get(uuid) is obj > assert session.query(Data).filter(Data.uuid == uuid).first() is obj > > Both asserts fail when I do this. The problem appears to be conversion from > to a uuid.UUID instance in GUID.process_result_value: this always creates a > new UUID instance, which probably causes a miss when SQLAlchemy tries to find > an instance in its identify map. > > Is this a bug in the GUID example in the documentation, or is this something > that can be improved in the identity map? > > Wichert.
-- 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 post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
On May 6, 2013, at 23:22, Wichert Akkerman <wich...@wiggy.net> wrote:
|
from uuid import UUID from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.dialects import postgresql metadata = MetaData(bind=create_engine('sqlite://')) BaseObject = declarative_base(metadata=metadata) class GUID(TypeDecorator): """Platform-independent GUID type. Uses Postgresql's UUID type, otherwise uses CHAR(36), storing as stringified hex values. This implementation is based on the SQLAlchemy `backend-agnostic GUID Type <http://www.sqlalchemy.org/docs/core/types.html#backend-agnostic-guid-type>`_ example. """ impl = CHAR def load_dialect_impl(self, dialect): if dialect.name == 'postgresql': return dialect.type_descriptor(postgresql.UUID()) else: return dialect.type_descriptor(CHAR(36)) def process_bind_param(self, value, dialect): if value is None: return value elif dialect.name == 'postgresql': return str(value) else: if not isinstance(value, UUID): return str(UUID(value)) else: # hexstring return str(value) def process_result_value(self, value, dialect): if value is None: return value else: return UUID(value) class Data(BaseObject): __tablename__ = 'data' uuid = Column(GUID(), primary_key=True) metadata.create_all() session = sessionmaker(autocommit=False)() uuid = 'ac4daeff-3af3-4b83-b8c7-3aa34e34151c' obj = Data(uuid=uuid) session.add(obj) assert session.query(Data).get(uuid) is obj assert session.query(Data).filter(Data.uuid == uuid).first() is obj