Thanks for the detailed response! Inserting the values seems to work fine now. Only retrieving them again doesn't work. I've updated the gist at https://gist.github.com/4433940
The problem seems that psycopg2 now returns the array as a string ({uuid1, uuid2}) and sqlalchemy iterates over the string instead of the containing elements. Bug in sqlalchemy or am i'm doing something stupid? :-) Thanks again! On Wed, Jan 2, 2013 at 5:23 PM, Michael Bayer <mike...@zzzcomputing.com> wrote: > OK well there's a lot of unfortunate turns on this one, at the core is that > psycopg2 by default doesn't know how to accept a list of UUIDs. The > postgresql.UUID() type in SQLAlchemy takes the easy approach and just > converts the value to a string, provided you pass the as_uuid=True flag to > it. That works for scalar UUID columns in Postgresql, however if we're > dealing with an array, then more casting is required as the data is passed > to the DB. Creating type processors on the psycopg2 side would be one > way to do this, though we can also do it on the SQLAlchemy side. > > Compounding issues here is that the array() construct in 0.8 has a tiny bug, > that's the "self_group()" error you got, but if we make that work, we still > have to cast each individual uuid() value inside the array which is the part > PG isn't doing here. > > If we fix the ARRAY.self_group() method, this approach works: > > def cast_uuid(value): > return cast(literal(uuid.uuid4(), UUID(as_uuid=True)), UUID) > > stmt = table.insert().values( > timestamp=datetime.datetime.utcnow(), > guids=array([cast_uuid(uuid.uuid4()), cast_uuid(uuid.uuid4())]) > ) > > > you get a statement like this: > > INSERT INTO example (timestamp, guids) VALUES (%(timestamp)s, > ARRAY[CAST(%(param_1)s AS UUID), CAST(%(param_2)s AS UUID)]) > 2013-01-02 11:07:47,850 INFO sqlalchemy.engine.base.Engine {'timestamp': > datetime.datetime(2013, 1, 2, 16, 7, 47, 849197), 'param_1': > 'cdeec87a-4915-4bc7-a688-8557cc760fe4', 'param_2': > '7215808a-64ff-43fa-98af-1d3fc07e75d8'} > > But there's an even better approach here which is to use SQL bind > processing, which also doesn't trip the array() bug at the moment and is > more transparent: > > class UUID_ARRAY(TypeDecorator): > impl = ARRAY(UUID(as_uuid=True), dimensions=1) > > def bind_expression(self, bindvalue): > val = bindvalue.value > if val is None: > val = [] > return array( > cast(literal(str(uuid_val)), UUID()) > for uuid_val in val > ) > > table = Table('example', metadata, > Column('timestamp', DateTime(timezone=False), primary_key=True), > Column('guids', UUID_ARRAY()) > ) > > stmt = table.insert().values( > timestamp=datetime.datetime.utcnow(), > guids=[uuid.uuid4(), uuid.uuid4()]) > engine.execute(stmt) > > > the SQL output is the same. > > > > > > > > > > On Jan 2, 2013, at 8:02 AM, Michael van Tellingen wrote: > > Hi all, > > I'm experimenting a bit with postgresql arrays of uuid's. > Unfortunately I'm running into a bug or I'm not really understanding > it :-) > > My schema definition is as follow: > > table = Table('example', metadata, > Column('timestamp', DateTime(timezone=False), primary_key=True), > Column('guids', ARRAY(GUID, dimensions=1) > ) > > Where GUID is taken from > http://docs.sqlalchemy.org/en/rel_0_8/core/types.html#backend-agnostic-guid-type > > Then I try to insert a row with the following code: > > stmt = table.insert().values( > timestamp=datetime.datetime.utcnow(), > guids=[uuid.uuid4()] > ) > engine.execute(stmt) > > This results in an ProgrammingError (column "guids" is of type uuid[] > but expression is of type text[] at character 97). > When using guids=array([uuid.uuid4()], type_=GUID) i receive the > following exception: > TypeError: self_group() takes exactly 2 arguments (1 given) > > The complete runnable code is located at https://gist.github.com/4433940 > > Am I missing something or do I need to register a custom type via psycopg2? > > Thanks, > Michael > > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To view this discussion on the web visit > https://groups.google.com/d/msg/sqlalchemy/-/23G5PmB2sYcJ. > To post to this group, send email to sqlalchemy@googlegroups.com. > To unsubscribe from this group, send email to > sqlalchemy+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/sqlalchemy?hl=en. > > > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To post to this group, send email to sqlalchemy@googlegroups.com. > To unsubscribe from this group, send email to > sqlalchemy+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.