Thanks for the follow up. Upon further reading/reflection, I discovered that wrapping my string IP address values in the psycopg2.extras.Inet object and then passing that in -- and executing psycopg2.extras.register_inet() as with the UUID example -- seems to work fine for both ORM and non-ORM.
So, it sounds like I can get the data into the right form without too many hoops. I will probably create a custom TypeDecorator that simply wraps incoming values in the Inet type (or convert from python netaddr objects into pg's Inet), but that seems like a relatively straightforward customization. Thanks again! Hans On Monday, January 7, 2013 10:09:53 AM UTC-5, Michael Bayer wrote: > > change again, that doesn't work. > > Upon reflection, I think the case here is that there's no alternative but > to make sure psycopg2 can properly format the contents of the ARRAY itself. > This is because SQLAlchemy is producing a completed INSERT statement for > preparation, without the parameters actually filled in: > > INSERT INTO table (x) VALUES (%(x)s) > > > At that point, SQLAlchemy is done producing strings, and sends it off to > psycopg2 along with an array value for "x". So there is no opportunity > here for a user-defined bind expression generator to further modify the > expression above. More fundamentally, the above statement can be called > using DBAPI executemany(); each value for "x" can be an array of a > *different* length. So it's totally up to psycopg2 here to handle this > case, and it even suggests that prepared statements can't be used very > effectively with Postgresql ARRAY types (psycopg2 doesn't use prepared > statements AFAIK). > > > > On Jan 7, 2013, at 9:58 AM, Michael Bayer wrote: > > correction, this seems to work, though will try to improve: > > class UUID_ARRAY(TypeDecorator): > impl = ARRAY(UUID, dimensions=1) > > def bind_expression(self, bindvalue): > if bindvalue.callable: > val = bindvalue.callable() > else: > val = bindvalue.value > if val is None: > val = [] > elif not hasattr(val, '__iter__'): > return bindvalue > return array( > cast(literal(str(uuid_val)), UUID()) > for uuid_val in val > ) > > > > > On Jan 7, 2013, at 9:55 AM, Michael Bayer wrote: > > this is ticket http://www.sqlalchemy.org/trac/ticket/2648 and cannot be > worked around at this time. If you're working with arrays of UUID I'd > recommend using psycopg2 type processors, as the previous poster has had > success with. > > > > On Jan 7, 2013, at 9:39 AM, Hans Lellelid wrote: > > I am looking to adapt this code for a related array/type issue. The code > from https://gist.github.com/4433940 works just fine for me (as expected) > when building/executing the stmt directly, but not when using the ORM. > > When row is created using ORM, like this: > > # <snip> > s = Session(bind=engine) > e = Example() > e.timestamp=datetime.datetime.utcnow(), > e.num=2, > e.guids = [uuid.uuid4(), uuid.uuid4()] > s.add(e) > s.commit() > > I get an error like this: > > <snip> > return getter(visitor)(self, **kw) > File > "/home/hans/workspace/providence/env/lib/python2.7/site-packages/SQLAlchemy-0.8.0b2-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py", > > line 760, in visit_bindparam > bind_expression = bindparam.type.bind_expression(bindparam) > File "test_array.py", line 38, in bind_expression > for uuid_val in val > TypeError: 'object' object is not iterable > > (I can dump in full stack if that would be helpful.) > > Indeed, inspecting that reveals that it is simply an object() instance. > I'm not sure where that is being set or whether there is an obvious > workaround here. I'm sure I'm simply missing obvious when it comes to > dealing with native array types and ORM entity instances. > > Thanks, > Hans > > -- > 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/-/ZwxFp2iasq0J. > To post to this group, send email to sqlal...@googlegroups.com<javascript:> > . > To unsubscribe from this group, send email to > sqlalchemy+...@googlegroups.com <javascript:>. > 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 sqlal...@googlegroups.com<javascript:> > . > To unsubscribe from this group, send email to > sqlalchemy+...@googlegroups.com <javascript:>. > 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 sqlal...@googlegroups.com<javascript:> > . > To unsubscribe from this group, send email to > sqlalchemy+...@googlegroups.com <javascript:>. > 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 view this discussion on the web visit https://groups.google.com/d/msg/sqlalchemy/-/0is1EGS0798J. 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.