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:

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.

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

Reply via email to