On Mar 5, 2013, at 9:45 AM, Jason <ja...@deadtreepages.com> wrote:
> Hello,
>
> I'm looking or some direction on how to implement the SQL syntax when querying Postgres' composite types. In case you're unfamiliar: the composite types in Postgres are a type that contains attributes which are regular SQL types. The attribute to type relationship is similar to the column to table relationship (except there are no constraints on attributes). A table column can be this composite type. Psycopg2 implements this by instantiating a namedtuple on retrieval or accepting a namedtuple on update/insert (you can also use your own custom class). The saving and retrieval isn't a problem with SQLAlchemy, I just pass through the namedtuple to/from Psycopg2.
>
> What I need to implement is the SQL syntax for querying composite type attributes. Postgres allows this by using the syntax "(table_name.column_name).attribute_name = 'bleh'" or just "(column_name).attribute_name = 'bleh'" when a table identifier is not required. I'm not sure how to go about this because the sql generation needs to change the way the column name is output, would this require subclassing the ColumnClause? I think I just need to know where to override the behaviour of generating the qualified column name in statements.
you'd be doing ColumnElement here which is the more fundamental object. It's discussed here in "subclassing guidelines": http://docs.sqlalchemy.org/en/rel_0_8/core/compiler.html#subclassing-guidelines
if you're on 0.8 the integration here can be very smooth, using custom operators (http://docs.sqlalchemy.org/en/rel_0_8/core/types.html#types-operators) you could have an approach that looks like: mytable.c.column.attrs.attribute_name == "value". The "attrs" namespace would call into your custom ColumnElement.
Since the custom operator API is a total blast to use here's a proof of concept:
On Tuesday, March 5, 2013 11:09:00 AM UTC-5, Michael Bayer wrote:
On Mar 5, 2013, at 9:45 AM, Jason <ja...@deadtreepages.com> wrote:
> Hello,
>
> I'm looking or some direction on how to implement the SQL syntax when querying Postgres' composite types. In case you're unfamiliar: the composite types in Postgres are a type that contains attributes which are regular SQL types. The attribute to type relationship is similar to the column to table relationship (except there are no constraints on attributes). A table column can be this composite type. Psycopg2 implements this by instantiating a namedtuple on retrieval or accepting a namedtuple on update/insert (you can also use your own custom class). The saving and retrieval isn't a problem with SQLAlchemy, I just pass through the namedtuple to/from Psycopg2.
>
> What I need to implement is the SQL syntax for querying composite type attributes. Postgres allows this by using the syntax "(table_name.column_name).attribute_name = 'bleh'" or just "(column_name).attribute_name = 'bleh'" when a table identifier is not required. I'm not sure how to go about this because the sql generation needs to change the way the column name is output, would this require subclassing the ColumnClause? I think I just need to know where to override the behaviour of generating the qualified column name in statements.
you'd be doing ColumnElement here which is the more fundamental object. It's discussed here in "subclassing guidelines": http://docs.sqlalchemy.org/en/rel_0_8/core/compiler.html#subclassing-guidelines
if you're on 0.8 the integration here can be very smooth, using custom operators (http://docs.sqlalchemy.org/en/rel_0_8/core/types.html#types-operators) you could have an approach that looks like: mytable.c.column.attrs.attribute_name == "value". The "attrs" namespace would call into your custom ColumnElement.
Since the custom operator API is a total blast to use here's a proof of concept:
Wow thats great, thanks!There is a problem with this when using declarative and a reflected base. My Column's type get's overrwritten with NullType even though I've set autoreload_replace=False when constructing the table. I am still using the example ReflectedBase that was in the 0.7 documentation (because the new DeferredReflection class in 0.8 raises a NoReferencedTableError when configure_mappers() is called). Any idea how this reflected base is overwriting the type?:
--
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+...@googlegroups.com.
To post to this group, send email to sqlal...@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.
could you point me in the right direction how to "set it up correctly"? I'm currently a bit lost in the documentation and code.
I've added a small standalone script at https://gist.github.com/Turbo87/5233888The output is "SELECT (SomeFunction("table".foo)).attr1 AS anon_1", without any FROM clause.
Hi Michael, thanks for the explanation on the key attribute. I ended up misunderstanding it at first, but it seems to work now.I had a few problems when I tried to use a UserDefinedType (e.g. geoalchemys Geometry) in the typemap, because it complained about a missing "key" attribute. I've fixed that by adding "key = None" to the comparator class though (https://github.com/Turbo87/geoalchemy2/commit/264c7cd578da78c5c5f964ecd44c35a307923643) and it seems to work as expected now :)
GeoAlchemy is for SQLALchemy =<0.7.xGeoAlchemy2 if for SQLALchemy =>0.8