I can send an example later, but first I'll describe the general scenario 
which may be causing the issue. I dug through the codebase and removed any 
code that I thought could be potentially causing some weird object aliasing 
problems. To provide some insight, I'm building an adhoc query tool that 
allows a user to iteratively refine a query, so the expected workflow is as 
follows:

- Build initial query by selecting the columns desired.
- Serialize it, assign a unique ID and save it to the database
- Fetch from the database, unserialize it, and apply a filter in the form 
of a where condition, e.g. BIOPSY.SITE_DISTANCE > 5.0
- Serialize the new query with the applied filter and assign it a new, 
unique ID, then save to the database
- Repeat

Each time, I'm passing in the the same Engine, Session, and Metadata 
instance to sqlalchemy.ext.serializer.Deserializer.

This could be a detail of the implementation of SA, and as a result 
tangential, but after digging through the internals of each unserialized 
Select, 
I can see that the internal Table objects referenced in the From clause 
have changed via the builtin id() function.

Thanks for your help.

- Mike


On Thursday, November 14, 2013 10:36:36 AM UTC-5, Michael Bayer wrote:
>
>
> On Nov 14, 2013, at 10:18 AM, Michael Woods <mikes...@gmail.com<javascript:>> 
> wrote:
>
> Hi SA community
>
> This issue has been bugging me for a while. Hopefully someone has some 
> input, since this issue is really impeding my work at this point.
>
> Using the following code 
>
>   query_object = select([id_column] + columns, 
>                        and_(*where_clauses), 
>                        from_parts, 
>                        use_labels=True, 
>                        correlate=False, 
>                        distinct=True)
>
> I am able to produce the valid query:
>
> SELECT DISTINCT accard."ESOPH_REGISTRY"."PTID" AS 
> "accard_ESOPH_REGISTRY_PTID",
>                 accard."ESOPH_REGISTRY_VW"."GENDER" AS 
> "accard_ESOPH_REGISTRY_VW_GENDER",
>                 accard."ESOPH_REGISTRY_VW"."LAST_NAME" AS 
> "accard_ESOPH_REGISTRY_VW_LAST_NAME",
>                 accard."ESOPH_REGISTRY_VW"."FIRST_NAME" AS 
> "accard_ESOPH_REGISTRY_VW_FIRST_NAME",
>                 accard."ESOPH_REGISTRY"."RACE" AS 
> "accard_ESOPH_REGISTRY_RACE",
>                 accard."ESOPH_BIOPSY"."SPECIMEN_NO" AS 
> "accard_ESOPH_BIOPSY_SPECIMEN_NO",
>                 accard."ESOPH_BIOPSY"."SITE_DISTANCE_CM" AS 
> "accard_ESOPH_BIOPSY_SITE_DISTANCE_CM",
>                 accard."ESOPH_BIOPSY"."PATHOLOGY_CODE" AS 
> "accard_ESOPH_BIOPSY_PATHOLOGY_CODE"
> FROM accard."ESOPH_REGISTRY",
>      accard."ESOPH_REGISTRY_VW"
> LEFT OUTER JOIN accard."MASTER_REGISTRY" ON 
> accard."ESOPH_REGISTRY_VW"."UUID" = accard."MASTER_REGISTRY"."UUID",
>                                             accard."ESOPH_BIOPSY"
> LEFT OUTER JOIN accard."ESOPH_ENDOSCOPY" ON 
> accard."ESOPH_BIOPSY"."FK_ENDOSCOPY_ID" = 
> accard."ESOPH_ENDOSCOPY"."PK_ENDOSCOPY_ID"
> WHERE accard."ESOPH_ENDOSCOPY"."PTID" = accard."ESOPH_REGISTRY"."PTID"
>     AND accard."MASTER_REGISTRY"."UUID" = accard."ESOPH_REGISTRY"."UUID"
>     AND accard."ESOPH_REGISTRY"."PTID" = accard."ESOPH_REGISTRY_VW"."PTID"
>     AND upper(accard."ESOPH_ENDOSCOPY"."DISPLAY") = 'Y'
>     AND upper(accard."ESOPH_BIOPSY"."DISPLAY") = 'Y'
>     AND upper(accard."ESOPH_REGISTRY"."DISPLAY") = 'Y'
>     AND upper(accard."MASTER_REGISTRY"."DISPLAY") = 'Y' LIMIT 250
>
> All is good and right with the world. 
>
> However, once I add a new where clause, an invalid query is produced, and 
> the source of my frustration begins. 
>
> For example, the following statement:
>
>   query_object.append_whereclause(esoph_biopsy.c['site_distance_cm'] > 5.0)
>
> produces the query:
>
> SELECT DISTINCT accard."ESOPH_REGISTRY"."PTID" AS 
> "accard_ESOPH_REGISTRY_PTID",
>                 accard."ESOPH_REGISTRY_VW"."GENDER" AS 
> "accard_ESOPH_REGISTRY_VW_GENDER",
>                 accard."ESOPH_REGISTRY_VW"."LAST_NAME" AS 
> "accard_ESOPH_REGISTRY_VW_LAST_NAME",
>                 accard."ESOPH_REGISTRY_VW"."FIRST_NAME" AS 
> "accard_ESOPH_REGISTRY_VW_FIRST_NAME",
>                 accard."ESOPH_REGISTRY"."RACE" AS 
> "accard_ESOPH_REGISTRY_RACE",
>                 accard."ESOPH_BIOPSY"."SPECIMEN_NO" AS 
> "accard_ESOPH_BIOPSY_SPECIMEN_NO",
>                 accard."ESOPH_BIOPSY"."SITE_DISTANCE_CM" AS 
> "accard_ESOPH_BIOPSY_SITE_DISTANCE_CM",
>                 accard."ESOPH_BIOPSY"."PATHOLOGY_CODE" AS 
> "accard_ESOPH_BIOPSY_PATHOLOGY_CODE"
> FROM accard."ESOPH_REGISTRY",
>      accard."ESOPH_BIOPSY",
>      accard."ESOPH_REGISTRY_VW"
> LEFT OUTER JOIN accard."MASTER_REGISTRY" ON 
> accard."ESOPH_REGISTRY_VW"."UUID" = accard."MASTER_REGISTRY"."UUID",
>                                             accard."ESOPH_BIOPSY"
> LEFT OUTER JOIN accard."ESOPH_ENDOSCOPY" ON 
> accard."ESOPH_BIOPSY"."FK_ENDOSCOPY_ID" = 
> accard."ESOPH_ENDOSCOPY"."PK_ENDOSCOPY_ID"
> WHERE accard."ESOPH_ENDOSCOPY"."PTID" = accard."ESOPH_REGISTRY"."PTID"
>     AND accard."MASTER_REGISTRY"."UUID" = accard."ESOPH_REGISTRY"."UUID"
>     AND accard."ESOPH_REGISTRY"."PTID" = accard."ESOPH_REGISTRY_VW"."PTID"
>     AND upper(accard."ESOPH_ENDOSCOPY"."DISPLAY") = 'Y'
>     AND upper(accard."ESOPH_BIOPSY"."DISPLAY") = 'Y'
>     AND upper(accard."ESOPH_REGISTRY"."DISPLAY") = 'Y'
>     AND upper(accard."MASTER_REGISTRY"."DISPLAY") = 'Y'
>     AND accard."ESOPH_BIOPSY"."SITE_DISTANCE_CM" > 5.0 LIMIT 250
>
> When run, it produces the error  <OperationalError> ambiguous column 
> name: accard.ESOPH_BIOPSY.SPECIMEN_NO, which is understandable, considering 
> the table ESOPH_BIOPSY appears twice in the FROM clause--once as a 
> standalone table, and once in a join: 
>
> accard."ESOPH_BIOPSY" LEFT OUTER JOIN accard."ESOPH_ENDOSCOPY" ON 
> accard."ESOPH_BIOPSY"."FK_ENDOSCOPY_ID" = 
> accard."ESOPH_ENDOSCOPY"."PK_ENDOSCOPY_ID"
>
> I'm not doing anything strange in the construction of the Select object 
> via select(). The value of from_parts contains 5 items: the 2 standalone 
> tables (accard."ESOPH_REGISTRY" and accard."ESOPH_REGISTRY_VW"), and the 2 
> joins.
>
> This is confusing behavior, as it contradicts the SQLAlchemy documentation 
> for select(), mainly the from_obj argument:
>
>
>    - *from_obj* – A list of 
> ClauseElement<http://docs.sqlalchemy.org/en/rel_0_8/core/sqlelement.html#sqlalchemy.sql.expression.ClauseElement>
>  objects 
>    which will be added to the FROM clause of the resulting statement. 
>    Note that “from” objects are automatically located within the columns and 
>    whereclause ClauseElements. Use this parameter to explicitly specify 
> “from” 
>    objects which are not automatically locatable. This could include 
> Table<http://docs.sqlalchemy.org/en/rel_0_8/core/metadata.html#sqlalchemy.schema.Table>
>  objects 
>    that aren’t otherwise present, or 
> Join<http://docs.sqlalchemy.org/en/rel_0_8/core/selectable.html?highlight=join#sqlalchemy.sql.expression.Join>
>  objects 
>    whose presence will supercede that of the 
> Table<http://docs.sqlalchemy.org/en/rel_0_8/core/metadata.html#sqlalchemy.schema.Table>
>  objects 
>    already located in the other clauses.
>
>
> My understanding of the above is that if I add a column to the WHERE 
> clause that references a table T, first all present FROM clause objects 
> will be checked for T first. If T appears in a join, T will not be added to 
> the FROM clause objects list. Likewise, if T already appears explictly in 
> the FROM clause it will not be added either.
>
> Am I missing something?
>
>
> you need to send along a real example that illustrates this effect, it 
> indicates that a copy of the Table, or an alias of some kind, is doubling 
> up on the FROM list.  this has to do with how the query was constructed in 
> the first place and without full specifics there’s no way to guess the 
> origins of this behavior.  Also it’s probably a good idea to use 
> select().where(), producing a new select() object, rather than 
> append_whereclause() - the latter can lead to confusion if you re-inject 
> pieces of the existing select() into itself.
>
>
>

-- 
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.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to