On 10/03/2016 07:41 PM, Andrew Kowalik wrote:
SQLAlchemy == 1.0.3
mysql-python == 1.2.5

I have been playing around with baked queries and have a couple
observations, one which is problem my lack of SQLA knowledge and the
other a possible feature.

1) .in_ and bindparam
I have a query that I am baking that uses in_ with a python list. For
example
baked_query += lambda q: q.filter(Model.attr1.in_([bindparam('attr1')])

that's not a supported argument form.  in_() generates SQL like this:

col IN (?, ?, ?, ?)

as you can see, the physical structure of the SQL is dependent on how many bound parameter items are in the list. So a single bound parameter cannot accommodate for this. I *think* that some of the MySQL and Postgresql drivers do attempt to receive a single list as a bound parameter and expand within IN() in some of these cases but SQLAlchemy knows nothing about that and it's not clear how those drivers accomplish this without parsing the SQL statement.

If you are trying to work with the underlying driver's auto-expansion of IN, I think at the very least you would not want to use in_([bindparam()]), you'd want to use in_(bindparam()) and I'm not sure SQLAlchemy allows that. You'd be better off building up a custom construct for now short of patching SQLAlchemy.



Generating the query in python succeeds but fails in mysql as bindparam
is not being converted to a valid representation for the list. "operand
should contain 1 column(s)". I tried to manually convert the python list
into a string of comma separated values, the query runs but I am doing
something stupid so the query returns zero results.

So because the physical structure of the IN statement is affected by the length of the argument list, this is not an appropriate target for something that would be "baked". Unless the underlying database driver is translating for a single bound parameter (and SQLAlchemy is letting you do that), you're going to get weird errors.



2) Result class currently does not support count(). I have a use case
where I want to allow the possibility to paginate a baked query and with
it, gather the total number of records. Without supporting count I am
having to call _as_query() and then call count on the returned query.

Result sets don't work that way. Relational databases do not send out the count of rows that would be expected separately, they simply start sending out rows and you have no idea how many there will be (nor does the database) until it has no more to send. So for count(), fetch the entire result set and do a length. Obviously this does not work for pagination. For pagination you at the very least need to do LIMIT/OFFSET at the SQL level and depending on platform and specifics you may want to use https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/WindowedRangeQuery.





Just some thoughts that I did not see brought up before in my searches.

--
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
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

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

Reply via email to