[sqlalchemy] Using identity_key in after_commit session event (SQLAlchemy 0.6.7)

2011-05-26 Thread Torsten Landschoff
Hi Michael et al,

basic question: Can I call identity_key in after_commit? If not, are there any 
alternatives?

Explanation:

For our GUI application I tried to extend SQLAlchemy to signal database
updates. The following constraints apply:
  * Updates are done in background threads and should be visible in
the GUI main thread.
  * Being a MVC architecture, the GUI shows only data as actually
found in the database.
All business objects implement the Observer pattern, so in-GUI changes
(not yet committed) are shown in the GUI panels. This can not be used
with background threads as the event is fired on attribute write -
before the change is committed.

The scheme I implemented is that a SessionExtension is keeping track of
dirty, new and deleted instances in after_flush and generates events in
after_commit. after_rollback clears the information of changed
instances.

To move the list of affected objects to another thread, I use the
identity_key function to retrieve the primary keys. On the target
thread, I use that information to reload ORM instances which are
affected.

However, while doing an unrelated change today, this broke down with the
following backtrace. I can not make sense out of this: after_commit
should only be called after a commit I would think (not after a rollback
as the error message seems to indicate).

I'd expect that identity_key should be available in after_commit as it
is called *after* a commit and therefore the session should be in a sane
state?! This error breaks the GUI, every later attribute access fails
with DetachedInstanceError.

Note: The mechanism is used also for same-thread updates and in this
case the after_commit actually runs in the GUI thread for the ORM
session used by the GUI thread.

Any hints much appreciated. Thanks!

Torsten

  File /home/torsten/workspace/loco2-git/loco2/storage/extensions.py, line 
96, in after_commit
notifier.signal_updated(instance)
  File /home/torsten/workspace/loco2-git/loco2/storage/notification.py, line 
72, in signal_updated
self._signal(_UPDATE, type(instance), identity_key(instance=instance))
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/util.py,
 line 185, in identity_key
return mapper.identity_key_from_instance(instance)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/mapper.py,
 line 1294, in identity_key_from_instance
self.primary_key_from_instance(instance))
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/mapper.py,
 line 1306, in primary_key_from_instance
return self._primary_key_from_state(state)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/mapper.py,
 line 1311, in _primary_key_from_state
column in self.primary_key]
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/mapper.py,
 line 1315, in _get_state_attr_by_column
return self._columntoproperty[column]._getattr(state, dict_, column, 
passive=passive)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/properties.py,
 line 121, in _getattr
return state.get_impl(self.key).get(state, dict_, passive=passive)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/attributes.py,
 line 388, in get
value = callable_(passive=passive)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/state.py,
 line 287, in __call__
self.manager.deferred_scalar_loader(self, toload)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/mapper.py,
 line 2499, in _load_scalar_attributes
only_load_props=attribute_names)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/query.py,
 line 1968, in _get
return q.one()
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/query.py,
 line 1656, in one
ret = list(self)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/query.py,
 line 1699, in __iter__
return self._execute_and_instances(context)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/query.py,
 line 1704, in _execute_and_instances
mapper=self._mapper_zero_or_none())
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/session.py,
 line 723, in execute
return self._connection_for_bind(engine, close_with_result=True).execute(
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/session.py,
 line 667, in _connection_for_bind
return self.transaction._connection_for_bind(engine)
  File 
/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.7dev-py2.6.egg/sqlalchemy/orm/session.py,
 line 319, in 

Re: [sqlalchemy] Using identity_key in after_commit session event (SQLAlchemy 0.6.7)

2011-05-26 Thread Torsten Landschoff
On Thu, 2011-05-26 at 08:34 +0200, Torsten Landschoff wrote:
 basic question: Can I call identity_key in after_commit? If not, are there 
 any alternatives?

A bit of extra information: My usage of identity_key stems from this
thread on this list:

http://groups.google.com/group/sqlalchemy/browse_frm/thread/f62edf05c2696723/a3fc24f29bad7123?lnk=gstq=identity_key#a3fc24f29bad7123

(Message-Id is 1276873541.4601.19.camel@sharokan.intern if anybody
cares)

Greetings, Torsten

-- 
DYNAmore Gesellschaft fuer Ingenieurdienstleistungen mbH
Torsten Landschoff

Office Dresden
Tel: +49-(0)351-4519587
Fax: +49-(0)351-4519561

mailto:torsten.landsch...@dynamore.de
http://www.dynamore.de

Registration court: Mannheim, HRB: 109659, based in Karlsruhe,
Managing director:  Prof. Dr. K. Schweizerhof, Dipl.-Math. U. Franz

-- 
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.



[sqlalchemy] Deferred properties are sometimes compiled unnecessarily?

2011-05-26 Thread Nathan Wright
Hi all,

I've run into an issue when mapping a deferred column_property that uses a 
custom SQL construct. I get a KeyError: 'default' because there is no 
compile function for the default dialect, but it seems to me that the 
default dialect should never be used.

Here's an extended stack trace of what's going on, the important bit is 
lines 78-90:
http://pastebin.com/0kVf9q9q

And here's the a simplified test case:

class utcnow(expression.FunctionElement):
type = DateTime()

@compiles(utcnow, 'postgresql')
def pg_utcnow(element, compiler, **kw):
return TIMEZONE('utc', CURRENT_TIMESTAMP)

mapper(AnyClass, any_table, properties={
'timestamp': column_property(select([utcnow()]), deferred=True)
})

Session.query(AnyClass).all() 


For now I'm just adding a dummy @compiles(utcnow) function for the default 
dialect, but I think this could be avoided entirely by changing the 
NoSuchColumnError message to not cast key (ie, the select) to a string. 
Perhaps the repr could be used instead?

If I'm way off base feel free to let me know, heh, but hopefully this helps! 
:)

Cheers,
Nathan

-- 
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.



Re: [sqlalchemy] Deferred properties are sometimes compiled unnecessarily?

2011-05-26 Thread Michael Bayer

On May 25, 2011, at 10:52 PM, Nathan Wright wrote:

 Hi all,
 
 I've run into an issue when mapping a deferred column_property that uses a 
 custom SQL construct. I get a KeyError: 'default' because there is no compile 
 function for the default dialect, but it seems to me that the default dialect 
 should never be used.
 
 Here's an extended stack trace of what's going on, the important bit is lines 
 78-90:
 http://pastebin.com/0kVf9q9q
 
 And here's the a simplified test case:
 
 class utcnow(expression.FunctionElement):
 type = DateTime()
 
 @compiles(utcnow, 'postgresql')
 def pg_utcnow(element, compiler, **kw):
 return TIMEZONE('utc', CURRENT_TIMESTAMP)
 
 mapper(AnyClass, any_table, properties={
 'timestamp': column_property(select([utcnow()]), deferred=True)
 })
 
 Session.query(AnyClass).all() 
 
 
 For now I'm just adding a dummy @compiles(utcnow) function for the default 
 dialect, but I think this could be avoided entirely by changing the 
 NoSuchColumnError message to not cast key (ie, the select) to a string. 
 Perhaps the repr could be used instead?

the __repr__() produces IMHO a less descriptive string in the case of a no 
such column type of situation:

sqlalchemy.exc.NoSuchColumnError: Could not locate column in row for column 
'sqlalchemy.sql.expression._Label object at 0x1124490'


Being able to see the expression is most meaningful.

http://www.sqlalchemy.org/trac/ticket/2178 provides a patch, which is an 
improvement on the situation.

-- 
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.



Re: [sqlalchemy] Using identity_key in after_commit session event (SQLAlchemy 0.6.7)

2011-05-26 Thread Michael Bayer

On May 26, 2011, at 2:34 AM, Torsten Landschoff wrote:

 Hi Michael et al,
 
 basic question: Can I call identity_key in after_commit? If not, are there 
 any alternatives?

absolutely.  identity_key is strictly informational with regards to the state 
present on the target object.

 To move the list of affected objects to another thread, I use the
 identity_key function to retrieve the primary keys. On the target
 thread, I use that information to reload ORM instances which are
 affected.

I would take care not to access any attributes on a session-attached object in 
a different thread than the originating thread of that Session (which 
identity_key() does).   This would constitute sharing of the Session's 
functionality across threads which is not threadsafe.

 
 However, while doing an unrelated change today, this broke down with the
 following backtrace. I can not make sense out of this: after_commit
 should only be called after a commit I would think (not after a rollback
 as the error message seems to indicate).

The stacktrace doesn't reveal the source of the issue as the source of the 
Session.commit() call is not shown.   after_commit() is only called as a direct 
result of Session.commit(), or in the case that you're using a Session in 
autocommit mode (to which I would advise, don't) it would be called in the 
scope of flush().   But only if the flush() succeeded - otherwise the exception 
is propagated before commit() is reached.


-- 
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.



[sqlalchemy] Why we don't have a contains_eager_all?

2011-05-26 Thread Israel Ben Guilherme Fonseca
Hi,

Just a easy question, why we don't have a contains_eager_all like we do with
joinedload?

By the way, I don't exactly understand why we shouldn't use the _all version
always.

Example (from
http://www.sqlalchemy.org/docs/orm/loading.html?highlight=contains_eager#contains-eager
):

query(User).options(contains_eager('orders', 'items'))


With this we are only loading the items of the orders objects. But to access
it, I must pass through the orders relation anyway, but without another:

contains_eager('orders')


It would make a new select, so I didn't get whats the use case of eager
loading the deepest children without loading all the way to it too.


(or maybe I'm wrong and it's behavior is like what I said and I'm missing
something in my tests)

Thanks in advance,


--

Bonus question: Wouldnt be nice if the joinedload (and all the variants)
could be used in the Query object? Ex:

query(User).joinedload('orders').all() is much more readable than:
query(User).options(joinedload('orders').all()

-- 
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.



[sqlalchemy] Injecting custom comment into SQL generated by query(Clazz).all()

2011-05-26 Thread Tomasz Nazar
Hi,

I got this habit of looking at which queries currently are live on
mysql db (via innotop).
And I like to add query name to each query.. example:

SELECT /* custom comment here...users living in Poland */ id FROM
users WHERE country = 'pl';

This way I can quickly identify queries that run/appear too slow/often..

How can I inject custom query text into
query(User).filter(User.country=='pl').all()
to achieve the final query contains custom text/comment as in the
example below...?


Thanks for suggestions,
Tomasz


-- 
_i__'simplicity_is_the_key'__tomasz_nazar
_ii'i_am_concern_oriented'JKM-UPR
_iii__'patsystem.sf.net'___linux_user
_'aspectized.com'___prevayler

-- 
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.



Re: [sqlalchemy] Why we don't have a contains_eager_all?

2011-05-26 Thread Michael Bayer


On May 26, 2011, at 11:02 AM, Israel Ben Guilherme Fonseca wrote:

 Hi,
 
 Just a easy question, why we don't have a contains_eager_all like we do with 
 joinedload?

contains_eager() should always act in an all context since there's little use 
otherwise.   This was fixed in 0.7 and is ticket #2032:

http://www.sqlalchemy.org/trac/ticket/2032

07Migration is updated.

 
 By the way, I don't exactly understand why we shouldn't use the _all version 
 always.

You might want to load a list of A, each has a collection of B.  But you don't 
want the B's by default.  But, if you do in fact load a particular collection 
of B, you'd like them to eagerly load their C.

We're falling victim a bit to favoring a rare use case over a common one here, 
but that's how things have worked out and its not really worth changing around 
at this point.

 
 
 Bonus question: Wouldnt be nice if the joinedload (and all the variants) 
 could be used in the Query object? Ex:
 
 query(User).joinedload('orders').all() is much more readable than:
 query(User).options(joinedload('orders').all()

Again this is how things have worked out over the years, but also options() 
does have a use in that you can also make your own MapperOption objects, 
without any need to subclass Query.  So there is some consistency in that 
options() allows external functions to enter in and modify the state of Query, 
without Query having any awareness of them.


-- 
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.



Re: [sqlalchemy] Why we don't have a contains_eager_all?

2011-05-26 Thread Israel Ben Guilherme Fonseca
Hmm, nice, I'm still with the 0.6.7, so that's why I missed it.

Thanks again for the superfast-effective answer.

2011/5/26 Michael Bayer mike...@zzzcomputing.com



 On May 26, 2011, at 11:02 AM, Israel Ben Guilherme Fonseca wrote:

 Hi,

 Just a easy question, why we don't have a contains_eager_all like we do
 with joinedload?


 contains_eager() should always act in an all context since there's little
 use otherwise.   This was fixed in 0.7 and is ticket #2032:

 http://www.sqlalchemy.org/trac/ticket/2032

 07Migration is updated.


 By the way, I don't exactly understand why we shouldn't use the _all
 version always.


 You might want to load a list of A, each has a collection of B.  But you
 don't want the B's by default.  But, if you do in fact load a particular
 collection of B, you'd like them to eagerly load their C.

 We're falling victim a bit to favoring a rare use case over a common one
 here, but that's how things have worked out and its not really worth
 changing around at this point.



 Bonus question: Wouldnt be nice if the joinedload (and all the variants)
 could be used in the Query object? Ex:

 query(User).joinedload('orders').all() is much more readable than:
 query(User).options(joinedload('orders').all()


 Again this is how things have worked out over the years, but also options()
 does have a use in that you can also make your own MapperOption objects,
 without any need to subclass Query.  So there is some consistency in that
 options() allows external functions to enter in and modify the state of
 Query, without Query having any awareness of them.


  --
 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.



[sqlalchemy] help wanted: porting sqlalchemy-migrate for SQLAlchemy 0.7 and sqlalchemy-migrate maintenance

2011-05-26 Thread Jan Dittberner
Hello,

I work on making sqlalchemy-migrate [1] work with SQLAlchemy 0.7. I
fixed all broken unit tests except for one related to adding a new
column with a foreign key to an existing table. We have a continues
integration system (Jenkins CI) at [2] that provides the output of the
failing test. The problem is with some changed behaviour of the
SchemaVisitor API (or the Column objects). Until SQLAlchemy 0.6 it was
possible to get the constraints object for the ForeignKey arguments of
a column. The test at [3] creates a new Column instance and adds it to
the table. Afterwards our ANSIColumnGenerator [4] is triggered to
generate the necessary SQL statements. Until SQLAlchemy 0.6 the code
for generating the foreign key constraints could be generated properly
but now the constraint is None instead of a ForeignKeyConstraint. I
tried to just ignore fk.constraint if it is None, which expectedly did
not generate a statement. I also tried to construct a
ForeignKeyConstraint instance and pass that to the AddConstraint
constructor. This approach added a second ForeignKey instance to the
Column which is not desired too.

Can you please give me hints in the right direction or provide help to
fix this issue?

We would also like to invite interested developers to join the
sqlalchemy-migrate project because it has no maintainers with enough
time to keep it in a good shape. I think it would be great if the test
coverage and code quality would be improved but neither me nor the
other current maintainers have enough time to do these necessary
prerequisites. We have a quite long list of outstanding issues [5]
that need some triaging and fixes and should give a good start for
interested developers.

[1] http://code.google.com/p/sqlalchemy-migrate/
[2] http://jenkins.gnuviech-server.de/job/sqlalchemy-migrate-all/
[3] http://code.google.com/p/sqlalchemy-migrate/source/browse/migrate/tests/changeset/test_changeset.py#160
[4] http://code.google.com/p/sqlalchemy-migrate/source/browse/migrate/changeset/ansisql.py#87
[5] http://code.google.com/p/sqlalchemy-migrate/issues/list


Regards
Jan Dittberner

-- 
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.



Re: [sqlalchemy] Using identity_key in after_commit session event (SQLAlchemy 0.6.7)

2011-05-26 Thread Michael Bayer

On May 26, 2011, at 11:58 AM, Torsten Landschoff wrote:

 
 How much more context would be helpful? Basically, this is the top of
 the backtrace. Above of that call is only the event handler hierarchy.
 
  File /home/torsten/workspace/loco2-git/loco2/ui/wizard/importwizard.py, 
 line 69, in do_component_import
session.commit()

above is likely the offending line of code.   commit() should not be called if 
an exception has been raised within flush() - the Session is in a state whereby 
it is waiting for rollback() to be called.


 
 I am actually using autocommit=True and autoflush=False. The reason is
 that autoflush=True caused a bunch of errors as I load hierarchical data
 in bottom up fashion and SQLAlchemy tried to flush objects to the
 database before a parent was available.
 
 What's so bad about autocommit=True? I don't really remember why I ended
 up using it. It would probably suffice to replace most flush() calls
 with commit() and be done with it.

if you're using autocommit=True and you are not calling session.begin(), then 
session.commit() cannot be called in any case -there is no transaction present 
- it will raise an error directly:

from sqlalchemy.orm import Session

s = Session(autocommit=True)
s.commit()

output:

sqlalchemy.exc.InvalidRequestError: No transaction is begun.
  

autocommit=True is SQLAlchemy's original transaction behavior in the Session.  
It doesn't allow for the Session to have any context as to when it's safe to 
expire objects, and I can't currently think of any cases where it is truly 
needed for anything - it seems to be used either because it is misunderstood, 
as seems possibly the case here as it has nothing to do with autoflush, or 
because some users really don't want to have to figure out when their 
application should be saying commit(), which IMHO is a serious architectural 
problem.   It is also used by legacy code and for some Zope extensions where 
they'd like to call Session.begin() explicitly in order to control scope better 
(and even there I'm not sure if they truly need it).

 
 
 BTW: The error is not reproducible anymore.
 
 Greetings, Torsten
 
 -- 
 DYNAmore Gesellschaft fuer Ingenieurdienstleistungen mbH
 Torsten Landschoff
 
 Office Dresden
 Tel: +49-(0)351-4519587
 Fax: +49-(0)351-4519561
 
 mailto:torsten.landsch...@dynamore.de
 http://www.dynamore.de
 
 Registration court: Mannheim, HRB: 109659, based in Karlsruhe,
 Managing director:  Prof. Dr. K. Schweizerhof, Dipl.-Math. U. Franz
 
 -- 
 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.



[sqlalchemy] Subselect that references the outer select

2011-05-26 Thread Israel Ben Guilherme Fonseca
Hi,

I'm trying to construct a query that have a subquery, and that subquery
references the outer query attribute. It's almost working actually:

Intended select:

select * from curso c join matricula m on c.id_curso = m.id_curso
  where m.id_aluno = 1
  and m.data = (select max(sub.data) from matricula
sub
  where sub.id_aluno = m.id_aluno)

Query:

alias = aliased(Matricula)
subquery = session.query(func.max(alias.data)).filter(alias.id_curso
== Matricula.id_curso).subquery()
lista = session.query(Curso) \
   .join(Matricula) \
   .filter(Matricula.id_aluno == 1) \
   .filter(Matricula.data == subquery) \
   .all()

Result select:

SELECT curso.id_curso AS curso_id_curso, curso.area AS curso_area,
curso.carga_horaria AS curso_carga_horaria, curso.ementa AS curso_ementa,
curso.nome AS curso_nome
FROM curso JOIN matricula ON curso.id_curso = matricula.id_curso
WHERE matricula.id_aluno = 1 AND matricula.data = (SELECT
max(matricula_1.data) AS max_1

FROM matricula AS matricula_1, matricula

  WHERE matricula.id_curso = matricula_1.id_curso)

The only problem here is: the subselect is using two references to
matricula in the from clause:

FROM matricula AS matricula_1, matricula  this guy shouldn't exist.

I just want the matricula from the outer select.

Fixing that, and i'm done. But how can I do that?

Thanks in advance

-- 
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.



Re: [sqlalchemy] help wanted: porting sqlalchemy-migrate for SQLAlchemy 0.7 and sqlalchemy-migrate maintenance

2011-05-26 Thread Michael Bayer

On May 26, 2011, at 11:41 AM, Jan Dittberner wrote:

 Hello,
 
 I work on making sqlalchemy-migrate [1] work with SQLAlchemy 0.7. I
 fixed all broken unit tests except for one related to adding a new
 column with a foreign key to an existing table. We have a continues
 integration system (Jenkins CI) at [2] that provides the output of the
 failing test. The problem is with some changed behaviour of the
 SchemaVisitor API (or the Column objects). Until SQLAlchemy 0.6 it was
 possible to get the constraints object for the ForeignKey arguments of
 a column. The test at [3] creates a new Column instance and adds it to
 the table.

the linked samples don't make it clear what specific behavior in SQLAlchemy has 
changed.   From your description, it appears as though you are saying 
ForeignKeyConstraint is not generated for an append_column() operation.  Below 
is a test which illustrates this usage, it is the same in 0.6 and 0.7.  If you 
can alter this test case to illustrate the specific functionality that has 
changed on the SQLA side from 0.6 to 0.7, it may very well be a bug in 0.7 or 
some usage in Migrate that was never supported, but at the very least it would 
isolate the issue.

from sqlalchemy import Table, Column, ForeignKey, MetaData, Integer, 
ForeignKeyConstraint

m1 = MetaData()

t1 = Table('t1', m1,
Column('x', Integer, primary_key=True)
)

t2 = Table('t2', m1, 
Column('x', Integer, primary_key=True),
Column('added_inline', Integer, ForeignKey('t1.x'))
)

assert set([
fkc.columns[0].name 
for fkc in t2.constraints 
if isinstance(fkc, ForeignKeyConstraint)]) == set(['added_inline'])

t2.append_column(
Column('added_externally', Integer, ForeignKey('t1.x'))
)

assert set([
fkc.columns[0].name 
for fkc in t2.constraints 
if isinstance(fkc, ForeignKeyConstraint)]) == set(['added_externally', 
'added_inline'])



-- 
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.



Re: [sqlalchemy] or_(MyClass.relationship1.contains(item), MyClass.relationship2.contains(item)) returns empty list

2011-05-26 Thread Michael Bayer
This seems to be an issue of poor documentation on our part.   Here are new 
documentation elements, linked from the ORM tutorial which was previously the 
only place contains() was mentioned, fully describing the behavior of 
contains(), and how any() and outerjoin() are more appropriate if OR 
conjunctions are used:

http://www.sqlalchemy.org/docs/orm/internals.html#sqlalchemy.orm.properties.RelationshipProperty.Comparator.contains


On May 24, 2011, at 7:51 PM, Hector Blanco wrote:

 Hello everybody...
 
 Let's say I have a class like this:
 
 class Foo(declarativeBase):
  bars1 = relationship(Bar.Bar, secondary=foos_to_bars1,
 collection_class=set())
  bars2 = relationship(Bar.Bar, secondary=foos_to_bars2,
 collection_class=list())
 
 At a certain point, I want to get instances of Foos that have a
 bar (instance of Bar.Bar) in any of the relationships.
 
 If I try to do:
 
 def inAnyBar(bar)
query(Foo).filter(or_(Foo.bars1.contains(bar),
 Foo.bars2.contains(bar)).all()
 
 I get an empty result.
 
 It looks (to me) like I'm doing something like:
 
 query(Foo).join(Foo.bars1).filter(Foo.bars1.contains(bar)).join(Foo.bars2).filter(Foo.bars1.contains(bar))
 
 Since Foo.bars1 doesn't contain bar, the second filter gives empty results.
 
 I've been able to find a workaround with subqueries (each join+filter
 in a subquery, then or_ all the subqueries) but I'd like to know if
 there's a better way to do it...
 
 I'm still using SqlAlchemy 0.6.6, though.
 
 Thank you!
 
 -- 
 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.



[sqlalchemy] Re: Subselect that references the outer select

2011-05-26 Thread Israel Ben Guilherme Fonseca
I did a bit more of digging in the docs and found the 'select_from' method.
I thought that it would force the FROM statement to use ONLY what I pass as
argument. But it didn't.

session.query(func.max(alias.data)).select_from(alias).filter(alias.id_curso
== Matricula.id_curso).subquery()

It stills give-me two matricula in the from clause. The  ==
Matricula.id_curso, is still enforcing the another matricula in the
query.

2011/5/26 Israel Ben Guilherme Fonseca israel@gmail.com

 Hi,

 I'm trying to construct a query that have a subquery, and that subquery
 references the outer query attribute. It's almost working actually:

 Intended select:

 select * from curso c join matricula m on c.id_curso = m.id_curso
   where m.id_aluno = 1
   and m.data = (select max(sub.data) from matricula
 sub
   where sub.id_aluno = m.id_aluno)

 Query:

 alias = aliased(Matricula)
 subquery =
 session.query(func.max(alias.data)).filter(alias.id_curso ==
 Matricula.id_curso).subquery()
 lista = session.query(Curso) \
.join(Matricula) \
.filter(Matricula.id_aluno == 1) \
.filter(Matricula.data == subquery) \
.all()

 Result select:

 SELECT curso.id_curso AS curso_id_curso, curso.area AS curso_area,
 curso.carga_horaria AS curso_carga_horaria, curso.ementa AS curso_ementa,
 curso.nome AS curso_nome
 FROM curso JOIN matricula ON curso.id_curso = matricula.id_curso
 WHERE matricula.id_aluno = 1 AND matricula.data = (SELECT
 max(matricula_1.data) AS max_1

 FROM matricula AS matricula_1, matricula

 WHERE matricula.id_curso = matricula_1.id_curso)

 The only problem here is: the subselect is using two references to
 matricula in the from clause:

 FROM matricula AS matricula_1, matricula  this guy shouldn't exist.

 I just want the matricula from the outer select.

 Fixing that, and i'm done. But how can I do that?

 Thanks in advance


-- 
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.



Re: [sqlalchemy] help wanted: porting sqlalchemy-migrate for SQLAlchemy 0.7 and sqlalchemy-migrate maintenance

2011-05-26 Thread Jan Dittberner
2011/5/26 Michael Bayer mike...@zzzcomputing.com:

 On May 26, 2011, at 11:41 AM, Jan Dittberner wrote:

 Hello,

 I work on making sqlalchemy-migrate [1] work with SQLAlchemy 0.7. I
 fixed all broken unit tests except for one related to adding a new
 column with a foreign key to an existing table. We have a continues
 integration system (Jenkins CI) at [2] that provides the output of the
 failing test. The problem is with some changed behaviour of the
 SchemaVisitor API (or the Column objects). Until SQLAlchemy 0.6 it was
 possible to get the constraints object for the ForeignKey arguments of
 a column. The test at [3] creates a new Column instance and adds it to
 the table.

 the linked samples don't make it clear what specific behavior in SQLAlchemy 
 has changed.   From your description, it appears as though you are saying 
 ForeignKeyConstraint is not generated for an append_column() operation.  
 Below is a test which illustrates this usage, it is the same in 0.6 and 0.7.  
 If you can alter this test case to illustrate the specific functionality that 
 has changed on the SQLA side from 0.6 to 0.7, it may very well be a bug in 
 0.7 or some usage in Migrate that was never supported, but at the very least 
 it would isolate the issue.

 from sqlalchemy import Table, Column, ForeignKey, MetaData, Integer, 
 ForeignKeyConstraint

 m1 = MetaData()

 t1 = Table('t1', m1,
    Column('x', Integer, primary_key=True)
 )

 t2 = Table('t2', m1,
    Column('x', Integer, primary_key=True),
    Column('added_inline', Integer, ForeignKey('t1.x'))
 )

 assert set([
    fkc.columns[0].name
    for fkc in t2.constraints
    if isinstance(fkc, ForeignKeyConstraint)]) == set(['added_inline'])

 t2.append_column(
    Column('added_externally', Integer, ForeignKey('t1.x'))
 )

 assert set([
    fkc.columns[0].name
    for fkc in t2.constraints
    if isinstance(fkc, ForeignKeyConstraint)]) == set(['added_externally', 
 'added_inline'])


the table.append_column() call was the missing piece of information.
In SQLA 0.6 it was not needed, in SQLA 0.7 it seems to be required.
The table.create(col) call triggered the
ANSIColumnGenerator.visit_column(self, column) method and the column
object passed to the method had a ForeignKey instance with ForeignKey
objects' constraint properties set to a ForeignKeyConstraint instance
instead of None (as in SQLA 0.7).

I was able to fix the unit test by adding
self.table.append_column(col) for SQLA 0.7. I hope that the change in
http://code.google.com/p/sqlalchemy-migrate/source/detail?r=2426a14c98f556fc63be2d677378255bfd8e4c2f
is correct and does not only fix the test.


Regards
Jan Dittberner

-- 
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.



Re: [sqlalchemy] help wanted: porting sqlalchemy-migrate for SQLAlchemy 0.7 and sqlalchemy-migrate maintenance

2011-05-26 Thread Michael Bayer

On May 26, 2011, at 4:04 PM, Jan Dittberner wrote:

 the table.append_column() call was the missing piece of information.
 In SQLA 0.6 it was not needed, in SQLA 0.7 it seems to be required.

the Column is guaranteed not at all associated with a Table if you didn't call 
table.append_column(col).   Its a free standing object that's not in a 
meaningful state when used in a SQL schema context.

 The table.create(col) call triggered the
 ANSIColumnGenerator.visit_column(self, column) method and the column
 object passed to the method had a ForeignKey instance with ForeignKey
 objects' constraint properties set to a ForeignKeyConstraint instance
 instead of None (as in SQLA 0.7).

e theres nothing I can see in the source that looks anything like that .  
ForeignKey is virtually identical in 0.6 and 0.7.  The .constraint attribute is 
created when the ForeignKey is associated with a parent Table which occurs via 
the Column. I can't yet figure out a test that would behave differently on 
0.6 vs. 0.7.

 
 I was able to fix the unit test by adding
 self.table.append_column(col) for SQLA 0.7. I hope that the change in
 http://code.google.com/p/sqlalchemy-migrate/source/detail?r=2426a14c98f556fc63be2d677378255bfd8e4c2f
 is correct and does not only fix the test.

well if this is only the test that relies upon the table + col issue then you 
are probably OK.

-- 
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.



Re: [sqlalchemy] Re: Subselect that references the outer select

2011-05-26 Thread Israel Ben Guilherme Fonseca
I saw that, but I'm not using a subquery in the from clause. Maybe I wasn't
clear enough. Example:

outeruser = aliased(User)
inneruser = aliased(User)

innerselect = session.query(inneruser.id).filter(inneruser.id ==
outeruser.id).subquery()

At this point I already have a problem, the generated from clause is
something like:

from user as user_2, user as user_1

I didnt want the other user_2, because the filter statement is actually
referencing the user of the outerselect:

outerselect = session.query(outeruser).filter(outeruser.id == innerselect)

I expected that the innerselect referenced the id of the outer select.


(That example was really a useless scenario, I'll try to make a better one
later)

2011/5/26 Michael Bayer mike...@zzzcomputing.com

 take a look at
 http://www.sqlalchemy.org/docs/orm/tutorial.html#using-subqueries and note
 that when a subquery is used as a FROM clause, it acts like a table.   Use
 the .c. attribute.


 On May 26, 2011, at 3:34 PM, Israel Ben Guilherme Fonseca wrote:

 I did a bit more of digging in the docs and found the 'select_from' method.
 I thought that it would force the FROM statement to use ONLY what I pass as
 argument. But it didn't.

 session.query(func.max(alias.data)).select_from(alias).filter(alias.id_curso
 == Matricula.id_curso).subquery()

 It stills give-me two matricula in the from clause. The  ==
 Matricula.id_curso, is still enforcing the another matricula in the
 query.

 2011/5/26 Israel Ben Guilherme Fonseca israel@gmail.com

 Hi,

 I'm trying to construct a query that have a subquery, and that subquery
 references the outer query attribute. It's almost working actually:

 Intended select:

 select * from curso c join matricula m on c.id_curso = m.id_curso
   where m.id_aluno = 1
   and m.data = (select max(sub.data) from
 matricula sub
   where sub.id_aluno = m.id_aluno)

 Query:

 alias = aliased(Matricula)
 subquery =
 session.query(func.max(alias.data)).filter(alias.id_curso ==
 Matricula.id_curso).subquery()
 lista = session.query(Curso) \
.join(Matricula) \
.filter(Matricula.id_aluno == 1) \
.filter(Matricula.data == subquery) \
.all()

 Result select:

 SELECT curso.id_curso AS curso_id_curso, curso.area AS curso_area,
 curso.carga_horaria AS curso_carga_horaria, curso.ementa AS curso_ementa,
 curso.nome AS curso_nome
 FROM curso JOIN matricula ON curso.id_curso = matricula.id_curso
 WHERE matricula.id_aluno = 1 AND matricula.data = (SELECT
 max(matricula_1.data) AS max_1

   FROM matricula AS matricula_1, matricula

 WHERE matricula.id_curso = matricula_1.id_curso)

 The only problem here is: the subselect is using two references to
 matricula in the from clause:

 FROM matricula AS matricula_1, matricula  this guy shouldn't exist.

 I just want the matricula from the outer select.

 Fixing that, and i'm done. But how can I do that?

 Thanks in advance



 --
 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.


-- 
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.



Re: [sqlalchemy] Re: Subselect that references the outer select

2011-05-26 Thread Michael Bayer

On May 26, 2011, at 5:03 PM, Israel Ben Guilherme Fonseca wrote:

 I saw that, but I'm not using a subquery in the from clause. Maybe I wasn't 
 clear enough. Example:
 
 outeruser = aliased(User)
 inneruser = aliased(User)
 
 innerselect = session.query(inneruser.id).filter(inneruser.id == 
 outeruser.id).subquery()
 
 At this point I already have a problem, the generated from clause is 
 something like:
 
 from user as user_2, user as user_1
 
 I didnt want the other user_2, because the filter statement is actually 
 referencing the user of the outerselect:
 
 outerselect = session.query(outeruser).filter(outeruser.id == innerselect)
 
 I expected that the innerselect referenced the id of the outer select.

oh then you're looking for correlation:

innerselect = session.query(inneruser.id).filter(inneruser.id == 
outeruser.id).correlate(outeruser) 

outerselect = session.query(outeruser).filter(outeruser.id == 
innerselect.as_scalar())

for some reason the Query is disabling auto-correlation upon subquery(), 
.statement or as_scalar().   Sort of wish I had noticed that before releasing 
0.7.   Will add a ticket to possibly change that default for 0.8, see you in a 
year.


-- 
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.



Re: [sqlalchemy] Re: Subselect that references the outer select

2011-05-26 Thread Israel Ben Guilherme Fonseca
Sweet, it's working. :)

Now let's wait for the 0.8.

2011/5/26 Michael Bayer mike...@zzzcomputing.com


 On May 26, 2011, at 5:03 PM, Israel Ben Guilherme Fonseca wrote:

 I saw that, but I'm not using a subquery in the from clause. Maybe I wasn't
 clear enough. Example:

 outeruser = aliased(User)
 inneruser = aliased(User)

 innerselect = session.query(inneruser.id).filter(inneruser.id ==
 outeruser.id).subquery()

 At this point I already have a problem, the generated from clause is
 something like:

 from user as user_2, user as user_1

 I didnt want the other user_2, because the filter statement is actually
 referencing the user of the outerselect:

 outerselect = session.query(outeruser).filter(outeruser.id == innerselect)

 I expected that the innerselect referenced the id of the outer select.


 oh then you're looking for correlation:

 innerselect = session.query(inneruser.id).filter(inneruser.id ==
 outeruser.id).correlate(outeruser)

 outerselect = session.query(outeruser).filter(outeruser.id ==
 innerselect.as_scalar())

 for some reason the Query is disabling auto-correlation upon subquery(),
 .statement or as_scalar().   Sort of wish I had noticed that before
 releasing 0.7.   Will add a ticket to possibly change that default for 0.8,
 see you in a year.


  --
 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.



Re: [sqlalchemy] or_(MyClass.relationship1.contains(item), MyClass.relationship2.contains(item)) returns empty list

2011-05-26 Thread Hector Blanco
Thank you!

As I'm sure some of the people in the list already know, I also asked
this same question in StackOverflow, and I got a couple of interesting
answers.

Just in case:
http://stackoverflow.com/questions/6118783/sqlalchemy-check-if-one-object-is-in-any-relationship-or-object-relationship1

2011/5/26 Michael Bayer mike...@zzzcomputing.com:
 This seems to be an issue of poor documentation on our part.   Here are new 
 documentation elements, linked from the ORM tutorial which was previously the 
 only place contains() was mentioned, fully describing the behavior of 
 contains(), and how any() and outerjoin() are more appropriate if OR 
 conjunctions are used:

 http://www.sqlalchemy.org/docs/orm/internals.html#sqlalchemy.orm.properties.RelationshipProperty.Comparator.contains


 On May 24, 2011, at 7:51 PM, Hector Blanco wrote:

 Hello everybody...

 Let's say I have a class like this:

 class Foo(declarativeBase):
      bars1 = relationship(Bar.Bar, secondary=foos_to_bars1,
 collection_class=set())
      bars2 = relationship(Bar.Bar, secondary=foos_to_bars2,
 collection_class=list())

 At a certain point, I want to get instances of Foos that have a
 bar (instance of Bar.Bar) in any of the relationships.

 If I try to do:

 def inAnyBar(bar)
    query(Foo).filter(or_(Foo.bars1.contains(bar),
 Foo.bars2.contains(bar)).all()

 I get an empty result.

 It looks (to me) like I'm doing something like:

 query(Foo).join(Foo.bars1).filter(Foo.bars1.contains(bar)).join(Foo.bars2).filter(Foo.bars1.contains(bar))

 Since Foo.bars1 doesn't contain bar, the second filter gives empty results.

 I've been able to find a workaround with subqueries (each join+filter
 in a subquery, then or_ all the subqueries) but I'd like to know if
 there's a better way to do it...

 I'm still using SqlAlchemy 0.6.6, though.

 Thank you!

 --
 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.



-- 
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.