Re: [sqlalchemy] Re: [Distutils] inability to pass setup.py command line arguments to dependency setups
FWIW, it is perfectly possible to package the thing separately as Glyph seem to suggest, even if the feature is enabled through an option. For example, Debian does it: http://packages.debian.org/experimental/python-sqlalchemy-ext On Fri, May 7, 2010 at 19:56, Kent Bower k...@retailarchitects.com wrote: Just because there are configuration problems associated with adding a feature like the one I needed is absolutely no reason to abandon it when it can bring value to the tool if used correctly and in some circumstances. I considered some of those exact complications what if it was already installed, etc and with my company's project, where I am using this useful tool in a circumstance you may overlook (it is perfectly acceptable to have such a feature, *despite* the list of complications you mention), such a feature would have been very valuable. Since it is useful in my case, I understand it would be valuable for others as well. (I don't appreciate the aggressive tone of your reply, though, nor do I see how my good faith efforts to help others warrant this... how did I possibly offend you with my post??) On the other hand, I appreciate your correct solution as a good approach and I'll forward this idea to an author of SQLAlchemy for his consideration. On 5/7/2010 1:33 PM, Glyph Lefkowitz wrote: On May 7, 2010, at 9:09 AM, Kent wrote: Consider the case where you want your setup to install third-party software, but you want/need to pass an argument to the command line that runs python setup.py --argument install or python setup.py -- argument bdist_egg As far as I could research, this feature is unavailable. And for good reason, I should think. I really hope that nobody ever adds this feature. If you require SQLAlchemy to be installed --with-cextensions, then what happens when your package is installed in an environment that already has SQLAlchemy installed *without* that flag? Does it stomp on the existing installation? What if the user installed one already with that flag and some other flags as well? What if it's system-installed and you're doing a user-install? Basically, compile-time and install-time options are a configuration nightmare. They should represent only how and where a package is installed, not what features it has. The correct solution to your problem would be to get SQLAlchemy to fix its broken deployment setup and split itself into 2 packages, SQLAlchemyCExtensions and SQLAlchemy, and then have your project depend on both, not to try to cram installer options into the dependency language. For confirmation of this theory, you need look no further than the excruciating user-experience of source-based installation systems with 'variant' support, like gentoo's Portage and *BSD's Ports, versus the relatively non-excruciating experience of packaging systems which express compile-time options as different packages like Yum and Apt. -- Gaëtan de Menten -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalch...@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] PyODBCConnector dbapi question
On Fri, Apr 2, 2010 at 21:08, Bo Shi bs1...@gmail.com wrote: Hrm, some different errors pop up. I'll move the dialog to the ticket in question. http://www.sqlalchemy.org/trac/ticket/1757 Should be fixed now (hopefully). Could you test once more? Thanks, -- Gaëtan de Menten -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalch...@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] PyODBCConnector dbapi question
On Tue, Mar 30, 2010 at 19:32, Michael Bayer mike...@zzzcomputing.com wrote: Bo Shi wrote: pep 249 specifies list of tuples for fetchmany() and fetchall() Hrm, pep-249 seems to only specify sequence and sequence of sequences for the fetch*() functions, specifying list of tuples only as one possible example. Perhaps the C implementation of RowProxy is being too strict here? I'm surprised that pyodbc is the only dbapi implementation that this problem has occurred in... do all the other implementations subclass tuple for their rows? we run the tests all the time with Pyodbc, so I wasn't aware this was a pyodbc issue. I'd run without the c extensions for now. For our C extension to coerce into a tuple begins to add overhead and defeat the purpose of using the extensions in the first place, though Gaetan would have to answer this question. Supporting arbitrary sequences is cheaper than I expected (you pay more than previously only if the sequence is neither a tuple nor a list), so now we are still fast for usual DBAPIs and hopefully don't break on odd stuff (as long as it is a sequence). -- Gaëtan de Menten -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalch...@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: 0.6 and c extensions
On Sun, Mar 21, 2010 at 17:13, drakkan drakkan1...@gmail.com wrote: On 21 Mar, 14:31, Antoine Pitrou solip...@pitrou.net wrote: Le dimanche 21 mars 2010 à 02:10 -0700, drakkan a écrit : a really interesting feature in sa 0.6 are the c extensions, however I think they should be implemented using ctypes so if python ctypes extension is available (default in python =2.5 and available even for 2.4) the c extensions are used as default, ctypes cannot compile your own C code. Yes I know my question is why sqlalchemy wrote his own C code and not use ctypes? Correct me if I'm wrong, but AFAIK ctypes is a way to interface your Python code with external C libraries. You cannot create any new functionality with ctypes. And what I did for the C extension was rewrite in C the most speed-critical parts of *SQLAlchemy* (not of an external lib) ! I could have used cython (and I might actually rewrite what I have done thus far in cython at some point in the future), but ctypes??? -- Gaëtan de Menten -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalch...@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] Problems with 0.6beta1
On Wed, Feb 10, 2010 at 08:48, Chris chris.g@gmail.com wrote: Hi All Have just upgraded to this version and am having the following issue. I use a the execute method on a ScopedSession to run generic SQL Statements in a TextClause, in the resulting BufferedRowResultProxy object their used to list field keys with was all the names of the fields in the result set. This appears to have been removed. How do a get a list of the field name for my query IIRC, resultproxy.metadata.keys -- Gaëtan de Menten -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalch...@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] Problems with 0.6beta1
On Wed, Feb 10, 2010 at 09:04, Gaetan de Menten gdemen...@gmail.com wrote: On Wed, Feb 10, 2010 at 08:48, Chris chris.g@gmail.com wrote: Hi All Have just upgraded to this version and am having the following issue. I use a the execute method on a ScopedSession to run generic SQL Statements in a TextClause, in the resulting BufferedRowResultProxy object their used to list field keys with was all the names of the fields in the result set. This appears to have been removed. How do a get a list of the field name for my query IIRC, resultproxy.metadata.keys Sorry, that should read: resulproxy._metadata.keys -- Gaëtan de Menten -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalch...@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] manytomany optimisations
On Thu, Feb 4, 2010 at 17:25, Andrew ajpere...@googlemail.com wrote: I have a table of tasks which contain references to multiple children and parents (tasks can have multiple children and multiple parents in this example). These are defined as ManyToMany and so I get an extra table containing the links. If I select all tasks, how can I then see a particular tasks children without sqlalchemy making another query every time. I have a case where I want to get a list of say 500 tasks and their children but end up with 500 extra queries. Search for eagerloading/lazy=False in the documentation. You can configure it either on the relation, or on the query. HTH, -- Gaëtan de Menten http://openhex.org -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalch...@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] Hi,I found a codec bug,and I write a patch.
On Wed, Jan 13, 2010 at 10:16, 诚子 zhicheng1...@gmail.com wrote: detial please see http://my.unix-center.net/~WeiZhicheng/2010/01/13/sqlalchemy-0-6-unicodedecodeerror-bug-patch/ Well, if I understand correctly, you would like a workaround for a bad truncate algorithm in mysql (which apparently truncates in the middle of a multi-byte character). Are you sure it's not a configuration problem of mysql? I would be amazed if they don't provide a solution to this problem (though that wouldn't be the first time I'm amazed at mysql... sigh...). Now, as to solve your problem (assuming it's not solvable on mysql's side), I think passing another UnicodeDecodingError behavior for the decoder would be a better generic solution. This is not yet possible with the generic types on current SQLAlchemy. See http://www.sqlalchemy.org/trac/ticket/1257 In the meantime, you are free to use a custom type, or type decorator to provide whatever custom decoding mechanism you want. We can't accept your patch though, as it is too specific to your case and would provide a very unexpected behavior in some cases (what if the decoding error is not at the end of the string?). Hope it helps, -- Gaëtan de Menten http://openhex.org -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalch...@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] Elixir 0.7.1 released
I am very pleased to announce that version 0.7.1 of Elixir (http://elixir.ematia.de) is now available. As always, feedback is very welcome, preferably on Elixir mailing list. This release packs a few interesting new features (abstract classes and a new collection type providing explicit relative resolution of target entities) and some bug fixes. It is a safe upgrade from the 0.7.0 release. The full list of changes can be seen at: http://elixir.ematia.de/trac/browser/elixir/tags/0.7.1/CHANGES What is Elixir? - Elixir is a declarative layer on top of the SQLAlchemy library. It is a fairly thin wrapper, which provides the ability to create simple Python classes that map directly to relational database tables (this pattern is often referred to as the Active Record design pattern), providing many of the benefits of traditional databases without losing the convenience of Python objects. Elixir does not intend to replace SQLAlchemy's core features, and instead focuses on providing a simpler syntax for defining model objects when you do not need the full expressiveness of SQLAlchemy's manual mapper definitions. Mailing list http://groups.google.com/group/sqlelixir/about -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: How to get the character limit of a string or unicode table column
On Mon, Nov 16, 2009 at 06:57, BruceC bruce.co...@hp.com wrote: I'm trying to implement a character counter on all textarea fields in my Elixir-SQLA-Pylons app, need to find a way to determine the maximum number of characters a given column can hold, so I can supply the character counter with a Maximum characters value. Anyone know of a simple method of finding the size-limit of a column? I use some code which is along the lines of: prop_length = {} for prop in mapper.iterate_properties: if isinstance(prop, sqlalchemy.orm.properties.ColumnProperty): col = prop.columns[0] if isinstance(col, sqlalchemy.schema.Column): if col.type.__class__ in (sqlalchemy.Unicode, sqlalchemy.String): if col.type.length: prop_length[prop.key] = col.type.length -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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] odict for mapper properties?
Hi Mike, I see in r6413, that you use an ordered dictionary instead of a standard one for properties, in an attempt to fix some jython ordering annoyingness. Is this really necessary to be compliant with Jython? Would you care to explain? I'm quite puzzled as to how that change could have any effect... Thanks in advance, -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: odict for mapper properties?
On Mon, Oct 19, 2009 at 16:04, Michael Bayer mike...@zzzcomputing.com wrote: I see in r6413, that you use an ordered dictionary instead of a standard one for properties, in an attempt to fix some jython ordering annoyingness. Is this really necessary to be compliant with Jython? Would you care to explain? I'm quite puzzled as to how that change could have any effect... i.e. it doesn't make any difference except for a test that is testing for an exact SQL string. Doh! Should have looked at the test in question, that'd have been obvious. Sorry about this. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: relation does not honor order_by attribute
On Wed, Oct 14, 2009 at 08:34, robert rottermann rob...@redcor.ch wrote: I am using a one to many relation, and would like the result to be ordered by a field of the child table. however no order by statement is executed when I access the related property of the parent object. this is my declaration: mitarbeiter_table = Table('mitarbeiter', Base2.metadata, autoload=True) class mitarbeiterCL(Base2): __table__ = mitarbeiter_table abwesenheit_table = Table('abwesenheit', Base2.metadata, autoload=True) class abwesenheitCL(Base2): __table__ = abwesenheit_table mitarbeiter = relation( mitarbeiterCL, uselist=False, backref='abwesenheiten', order_by = abwesenheit_table.c.datumvon, ) The problem is that you are specifying the order_by on the wrong side of the relationship (ie on the ManyToOne side). You need to place the order_by on the OneToMany side, and in your precise example, that means, on the backref. mitarbeiter = relation( mitarbeiterCL, uselist=False, backref=backref('abwesenheiten', order_by=abwesenheit_table.c.datumvon) ) -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: Modifying the scopefunc of an existing ScopedSession
On Tue, Oct 13, 2009 at 16:49, Michael Bayer mike...@zzzcomputing.com wrote: We have a situation where we have an existing ScopedSession, but want to change its scopefunc. This sounds like a strange requirement, it is because we use elixir - the issue is discusses here: http://groups.google.com/group/sqlelixir/browse_thread/thread/623f190c1784e5e9 How could we do this? To test, we currently we do: elixir.session.registry.scopefunc = lambda: 1 (The default is thread-local) But we seem to still end up with different sessions in different threads. you have to set that up ahead of time. by default, the registry evaluates as a _TLocalRegistry which is hardcoded to threadlocal. Session = scoped_session(sessionmaker(), scopefunc=lambda: 1) Since I was curious about the reason this didn't work, I looked more closely at that part of the code and I don't like that __new__ trick: it doesn't really help simplify the code and can be surprising. Attached patch suppress it. Btw: Iwan, did you try: factory = elixir.session.session_factory elixir.session.registry = sqlalchemy.util.ScopedRegistry(maker, scope_func=your_scope_func) Kinda ugly, but should work... (hopefully) -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~--- Index: orm/scoping.py === --- orm/scoping.py (revision 6393) +++ orm/scoping.py (working copy) @@ -5,7 +5,8 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php import sqlalchemy.exceptions as sa_exc -from sqlalchemy.util import ScopedRegistry, to_list, get_cls_kwargs, deprecated +from sqlalchemy.util import ScopedRegistry, ThreadLocalRegistry, \ +to_list, get_cls_kwargs, deprecated from sqlalchemy.orm import ( EXT_CONTINUE, MapperExtension, class_mapper, object_session ) @@ -29,7 +30,10 @@ def __init__(self, session_factory, scopefunc=None): self.session_factory = session_factory -self.registry = ScopedRegistry(session_factory, scopefunc) +if scopefunc: +self.registry = ScopedRegistry(session_factory, scopefunc) +else: +self.registry = ThreadLocalRegistry(session_factory) self.extension = _ScopedExt(self) def __call__(self, **kwargs): Index: util.py === --- util.py (revision 6393) +++ util.py (working copy) @@ -1163,14 +1163,7 @@ scopefunc a callable that will return a key to store/retrieve an object. - If None, ScopedRegistry uses a threading.local object instead. - -def __new__(cls, createfunc, scopefunc=None): -if not scopefunc: -return object.__new__(_TLocalRegistry) -else: -return object.__new__(cls) def __init__(self, createfunc, scopefunc): self.createfunc = createfunc @@ -1196,8 +1189,8 @@ except KeyError: pass -class _TLocalRegistry(ScopedRegistry): -def __init__(self, createfunc, scopefunc=None): +class ThreadLocalRegistry(ScopedRegistry): +def __init__(self, createfunc): self.createfunc = createfunc self.registry = threading.local()
[sqlalchemy] Re: Modifying the scopefunc of an existing ScopedSession
On Wed, Oct 14, 2009 at 17:09, Gaetan de Menten gdemen...@gmail.com wrote: Btw: Iwan, did you try: factory = elixir.session.session_factory elixir.session.registry = sqlalchemy.util.ScopedRegistry(maker, scope_func=your_scope_func) Of course, that should read : factory = elixir.session.session_factory elixir.session.registry = sqlalchemy.util.ScopedRegistry(factory, scope_func=your_scope_func) -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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] Elixir 0.7.0 released!
I am very pleased to announce that version 0.7.0 of Elixir (http://elixir.ematia.de) is now available. As always, feedback is very welcome, preferably on Elixir mailing list. This release incorporates many small improvements and bug fixes across the board. Please look at http://elixir.ematia.de/trac/wiki/Migrate06to07 for detailed upgrade notes. The most relevant changes are probably: * Support for the 0.6 branch of SQLAlchemy. * A way to set default options on custom base classes so that their children inherit from them. * A change to the naming pattern used for the columns of self-referencial ManyToMany relationship. * A couple of new extensions to add data or execute custom DDL upon table creation. The full list of changes can be seen at: http://elixir.ematia.de/trac/browser/elixir/tags/0.7.0/CHANGES What is Elixir? - Elixir is a declarative layer on top of the SQLAlchemy library. It is a fairly thin wrapper, which provides the ability to create simple Python classes that map directly to relational database tables (this pattern is often referred to as the Active Record design pattern), providing many of the benefits of traditional databases without losing the convenience of Python objects. Elixir is intended to replace the ActiveMapper SQLAlchemy extension, and the TurboEntity project but does not intend to replace SQLAlchemy's core features, and instead focuses on providing a simpler syntax for defining model objects when you do not need the full expressiveness of SQLAlchemy's manual mapper definitions. Mailing list http://groups.google.com/group/sqlelixir/about --~--~-~--~~~---~--~~ 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] Session.mapper deprecation
Hi all, I've been trying to work around the Session.mapper deprecation warning in Elixir by providing the same functionality within Elixir. The question is whether _ScopedExt is considered deprecated too ? I guess it is but want to make sure to not duplicate code needlessly... -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: Session.mapper deprecation
On Wed, Sep 30, 2009 at 16:57, Michael Bayer mike...@zzzcomputing.com wrote: Gaetan de Menten wrote: I've been trying to work around the Session.mapper deprecation warning in Elixir by providing the same functionality within Elixir. The question is whether _ScopedExt is considered deprecated too ? I guess it is but want to make sure to not duplicate code needlessly... Yeah that would be part of it. I was going to advise that you make your extension call the original init first, *then* add to the session, This is what I've come up with anyway... since most issues are related to the current ordering. FWIW, I indeed had errors in our test suite when trying to add the instance to the session before doing the original init. These were all inheritance tests IIRC. The add to the session afterwards does not seem to produce any obvious errors. I can only hope there are no subtle ones either... This is still doable, but if you are using the init_instance events we have, it seems like those are hardwired to trigger the event before the old initializer runs. hmm. Although, the reverse ordering may have just as many issues and even the same ones, as the object can be added to the session via cascades and similar. Thanks for the insight, -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: Session will not commit within a class
On Wed, Aug 5, 2009 at 08:16, kportertxkporte...@gmail.com wrote: O on a side note would you recommend elixir over declarative_base? The biggest difference between the two is that Elixir can generate some columns and tables for you (using common patterns). Michael Bayer probably won't recommend Elixir since he wrote declarative and he doesn't like much the generate stuff approach taken by Elixir. Whether you like/want that feature or not should decide whether you go with Elixir or declarative. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: Session will not commit within a class
On Wed, Aug 5, 2009 at 08:13, kportertxkporte...@gmail.com wrote: UGGG! I have been fighting with this for a while. I never thought to just use an actual file for my db instead of using memory. I was using memory because I was only wanting to test things and didn't want to keep the data. Seems that perhaps due to cherrypy the database was being deleted. I later moved the create_all() statement into the index sub and found that it worked. Following that when I loaded a lot of info into the db and browsed to an outside website and back all the data was gone. In case you were wondering, the reason for all your troubles is simple: cherrypy is multi-threaded. SQLite in-memory databases are thread-local. If you call create_all in all your threads, you create tables in all the different databases created by each thread. When you later revisited your site, cherrypy served you the page through another thread, hence another database, hence you saw no data. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: sqlalchemy.exc.InvalidRequestError: Object 'Foo at 0x23b0690' is already attached to session '29012560' (this is '30924944')
On Sun, May 31, 2009 at 16:50, Michael Bayer mike...@zzzcomputing.com wrote: On May 30, 2009, at 1:56 AM, ericthompso...@gmail.com wrote: Upon reaching the instantiation of Foo, my code blows up with the error message in the subject. Now I realize this is often caused by threading issues - multiple threads, each with their own Session, trying to touch an entity without first merging that entity into the thread's local session. But my application is single-threaded and to the best of my knowledge I'm not creating any new sessions other than the ScopedSession that was created when I imported elixir. Even if I had attempted to create several sessions via elixir_session(), my understanding is that I would have been returned the same session because I haven't changed threads and elixir by default uses a ScopedSession. that is all correct. So why is Foo winding up in a new session (and how did it already get attached to my current session)? I haven't passed any options regarding the session in my entity definitions. I can't see anything here which would cause this. A frequent cause of this confusion is when a library makes use of the ScopedSession.mapper method which has the effect of objects being automatically added to a session without the need to say session.add(object) - but again confusion would only occur here if there is more han one session in use. FWIW, this is the case with Elixir by default. You can turn that behavior off if you want though. That explains why your new object gets attached to the current session as soon as you instanciate your class. I have no idea why it is using a different session though. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: Trac feed broken
On Tue, Feb 17, 2009 at 03:14, Michael Bayer mike...@zzzcomputing.com wrote: it says to me: Congratulations! [Valid RSS] This is a valid RSS feed. im not able to reproduce any issue in the straight FF reader. Seems like somebody else fixed it, because it works today. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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] Trac feed broken
It seems like there is some bad character in one of the ticket details as it's been a few days since I could access the Trac feed. My feed reader (liferea) complains of: XML Parsing Error: reference to invalid character number Location: file:/// Line Number 20, Column 14:pre | #x3; | ^ And it seems like it is rightfully complaining: http://feedvalidator.org/check.cgi?url=http%3A%2F%2Fwww.sqlalchemy.org%2Ftrac%2Ftimeline%3Fmilestone%3Don%26changeset%3Don%26ticket%3Don%26ticket_details%3Don%26wiki%3Don%26max%3D50%26daysback%3D90%26format%3Drss -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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] Article about Elixir/SQLAlchemy in Python Magazine
Hi all, For those who might be interested, I wrote an article for Python Magazine titled Creating a collection manager with Elixir. It has just been published in the January issue (http://www.pythonmagazine.com/c/issue/view/90). Within the article, I detail the creation of a simple collection manager using Elixir, SQLAlchemy, CherryPy and Genshi. If any of you happen to read it, I'd be very interested to hear what you think about it. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: Renaming Columns and Union - possible bug
On Mon, Dec 22, 2008 at 17:06, Eoghan Murray eoghanomur...@gmail.com wrote: The following example uses an elixir class: class MyE(Entity): id = Field(Integer, primary_key=True) f_1 = ManyToOne('OtherE') f_2 = ManyToOne('OtherE') date = Field(Date) MyE.query.select_from(union(MyE.table.select(), select([MyE.id, MyE.f_1.label('f_2'), MyE.f_2.label('f_1')]))).\ order_by([MyE.date]) I'm not sure what you are trying to do, but MyE.f_1 and MyE.f_2 are not column objects. f_1_id and f_2_id are. The following *might* work: MyE.query.select_from( union(MyE.table.select(), select([MyE.id, MyE.f_1_id.label('f_2_id'), MyE.f_2_id.label('f_1_id')]))).\ order_by([MyE.date]) This produces the following SQL: SELECT anon_1.id AS anon_1_id, anon_1.f_1 AS anon_1_f_1, anon_1.date AS anon_1_date FROM ( SELECT mye.id AS id, mye.f_1 AS f_1, mye.f_2 AS f_2, mye.date AS date FROM mye UNION ALL SELECT mye.id AS id, mye.f_2 AS f_1, mye.f_1 AS f_2, mye.date AS date FROM mye) AS anon_1 ORDER BY anon_1.date Which strangely omits the anon_1_f_2 column and so doesn't populate the mapper correctly (f_2 is populated with the contents of f_1) Is this a bug? I've upgraded SQLAlchemy to 0.5.0rc4 and also elixir to 0.6.1 but it still appears. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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: New plugins and data types
On Mon, Dec 8, 2008 at 10:31, Kless [EMAIL PROTECTED] wrote: Thanks! Anyway I've seen that it's better add extensions in Elixir, into a declarative layer, just as has been made in DataMapper. As I just said on the Elixir mailing list: not really. The ability to add new types is an SQLAlchemy feature, not an Elixir one, so there is no reason to add them only at the Elixir level. That said, I'm not sure those types belong in SQLAlchemy core. It *might* make sense to have them in SQLAlchemy.ext namespace? http://elixir.ematia.de/apidocs/elixir.ext.html On 7 dic, 14:54, Michael Bayer [EMAIL PROTECTED] wrote: we have a bitbucket mirror athttp://www.bitbucket.org/mirror/sqlalchemy/ On Dec 7, 2008, at 5:01 AM, Kless wrote: I agree in that the SQLalchemy core been more centralized but would be very well if there would be a distributed version control where can be added easily new types. See as example to dm-more [1] -- of Datamapper--, where there are many contributions and many of them are very interesting. [1]http://github.com/sam/dm-more/tree/master/dm-types/lib/dm-types http://github.com/sam/dm-more/tree/master -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: SQLAlchemy Sphinx Documentation Preview
Here are the suggestions that come to mind: - You should either get rid of, or (preferably) expand/replace the current top-level table of contents. As it is currently, there is only one useful link in there (API reference) and the table of contents block waste way too much space for just one link. I liked the old condensed table of contents which fit entirely on the screen without scrolling. - The vertical spacing between the li is slightly too large to my taste, making for too much scrolling. I'd prefer a spacing roughly equivalent to the old doc site. This issue might become mostly irrelevant if the first one is fixed. - Inside the Object Relational Tutorial section, the TOC is flat. The hierarchical one was better IMO. - The new API reference TOC is better IMO than the old one because it doesn't include all the classes. I always took a few sec to find what I wanted because there was too much information in there. - On the other hand, I find the TOC *inside* API reference sections to be lacking a reference to all public classes of the module, like there was in the old system, for example at: http://www.sqlalchemy.org/docs/05/sqlalchemy_schema.html Btw: there is no TOC in api/sqlalchemy/Database schema. On Wed, Dec 3, 2008 at 19:06, Michael Bayer [EMAIL PROTECTED] wrote: We've created a new branch and are in the process of migrating all of our documentation over to Sphinx. The process has gone well and we have a working demo of the full system online. By converting to Sphinx, we get the huge advantage of being on a standardized platform that everyone can understand and contribute towards. All kinds of wacky old code, some of it four or more years old, has been removed (and we thank it for its service). The docs are now split into Main Documentation and API Reference. Because Sphinx allows very flexible layout of docstring-generated documentation, Main Documentation is shrinking and the docstrings used by API Reference, which is an all new section that replaces the old straight down modules display, are growing dramatically, which means more documentation is centralized across the site/pydocs and there's less redundancy. What we are now looking for with regards to the demo is: - comments/suggestions regarding layout, styling. Some layout changes were forced by Sphinx, and others (most) are improvements that Sphinx allowed us to achieve. I'm not a CSS guru or a designer so suggested patches to the CSS and templates would be welcome. If Todd Grimason is out there, feel free to chime in :) . - proofreaders. The content on the demo is maybe 60% of the way there and we're combing through finding issues related to the Sphinx conversion, as well as things that have just been wrong all along. We would love to get patches against the doc build correcting as many issues as possible. - authors. No excuses now , we're on the most standard platform there is for docs. If you have better verbiage for sections or docstrings which aren't clear, are nonexistent (like many of the dialects) or are out of date (theres lots), we want to see suggestions. More elaborate suggestions regarding new sections and organization are welcome too as the structure is completely open ended. - people who understand LaTex to work on the PDF side of things. This one's totally over my head as far as how to get a pdf file out of this thing (pdflatex is fairly inscrutable on a mac). Sphinx 0.6 is required, which at the time of this writing is not yet released so you'll have to check out Sphinx from its mercurial repository if you want to do builds. View the content online at: http://www.sqlalchemy.org/docs/sphinxtest/ Checkout the SVN branch and do a build: http://svn.sqlalchemy.org/sqlalchemy/branches/sphinx -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Polymorphic concrete inheritance question
Hello all, I've been playing a bit with polymorphic concrete inheritance, and noticed that when you have several levels of polymorphic loading (ie my child class is also a parent class which I want to load polymorphically), the query for the top-level class includes the child polymorphic join while I don't see any reason to (its table is already contained in the parent join). See attached example. class A(object): ... class B(A): pass class C(B): pass The query ends up something like: SELECT [all_columns] FROM ([pjoin_abc]), ([pjoin_bc]) Am I using it wrong, or is this a bug? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~--- from sqlalchemy import * from sqlalchemy.orm import * metadata = MetaData() metadata.bind = 'sqlite:///' a_table = Table('a', metadata, Column('id', Integer, primary_key=True), Column('data1', String(20)) ) b_table = Table('b', metadata, Column('id', Integer, primary_key=True), Column('data1', String(20)), Column('data2', String(20)) ) c_table = Table('c', metadata, Column('id', Integer, primary_key=True), Column('data1', String(20)), Column('data2', String(20)), Column('data3', String(20)) ) metadata.create_all() class A(object): def __init__(self, **kwargs): for k, v in kwargs.iteritems(): setattr(self, k, v) class B(A): pass class C(B): pass pjoin_all = polymorphic_union({ 'a': a_table, 'b': b_table, 'c': c_table }, 'type', 'pjoin') pjoin_bc = polymorphic_union({ 'b': b_table, 'c': c_table }, 'type', 'pjoin_bc') a_m = mapper(A, a_table, with_polymorphic=('*', pjoin_all), polymorphic_on=pjoin_all.c.type, polymorphic_identity='a') b_m = mapper(B, b_table, inherits=a_m, concrete=True, with_polymorphic=('*', pjoin_bc), polymorphic_on=pjoin_bc.c.type, polymorphic_identity='b') c_m = mapper(C, c_table, inherits=b_m, concrete=True, polymorphic_identity='c') Session = sessionmaker() session = Session() a1 = A(data1='a1') b1 = B(data1='b1', data2='b1') c1 = C(data1='c1', data2='c1', data3='c1') session.add(a1) session.add(b1) session.add(c1) session.commit() metadata.bind.echo = True session.query(A).all() print * * 20, B, * * 20 session.query(B).all()
[sqlalchemy] Re: Polymorphic concrete inheritance question
On Wed, Dec 3, 2008 at 15:03, Michael Bayer [EMAIL PROTECTED] wrote: um yeah, actually this behavior is affecting all multi-level usage of polymorphic_union. So, while polymorphic_union is quite obviously (since nobody has noticed this pretty glaring issue) on the decline in the 0.5 series, this is quite severe and ill try to have a look at it today. Do you want a bug report for this? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Polymorphic concrete inheritance question
On Wed, Dec 3, 2008 at 16:04, Michael Bayer [EMAIL PROTECTED] wrote: this ones big, i can handle it. the attached patch makes your case work, but the problem represented here still makes itself apparent in other ways and I havent strength tested this patch. you might want to see if this patch works in all of your test cases. FWIW, my (only) more complete test involving polymorphic concrete inheritance passes too (and produces correct SQL). Your patch seem fine and doesn't seem to break unrelated tests. Thanks for the quick reaction time, as usual. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Uppercase column names in table.insert({ })
On Mon, Sep 29, 2008 at 4:46 PM, Itamar Ravid [EMAIL PROTECTED] wrote: Thanks for the answer, Mike. I was used to Oracle's behavior while writing raw SQL, in which the case of unquoted column identifiers doesn't matter. This behavior seems reasonable enough, although the inconsistency between the cursor description and SQLA's column identifiers could throw some people off. This causes the versioned plugin from Elixir.ext to fail on Oracle, so I'll submit a patch against it to lowercase column names in table.insert()'s. Thanks again. I can't accept this patch as it breaks for people using non-lowercase column names on non-Oracle database. See http://elixir.ematia.de/trac/ticket/73 Some comments: - it fails silently: Mike, is it expected that when you do: connection.execute(table.insert(), {inexistant_field: somevalue}), it doesn't complain in any way? - I really think this should be fixed at SA-level (probably in the reflection code), as we don't do anything fancy in there... Here is roughly what happens: my_table = Table(my_table, metadata, autoload=True) my_table2 = Table(my_table2, metadata, *[col.copy() for col in my_table.c]) metadata.create_all() values = my_table.select().execute().fetchone() connection.execute(my_table2.insert(), values) On Mon, Sep 29, 2008 at 5:39 PM, Michael Bayer [EMAIL PROTECTED] wrote: This is the expected behavior. SQLA operates in a case sensitive fashion whenever a table or column identifier is given in mixed case or upper case. Use all lower case for case insensitive. Since SQLA seeks to provide a database-agnostic API to the backend, this includes Oracle as well.case sensitive means that the identifier will be quoted, in which case the database expects to match the identifier against an identifier of the exact same characters. Oracle's usual UPPERCASE identifiers are in fact case insensitive. So for case insensitive identifiers, make sure you use all lower case names like 'book_id'. The keys() method of the ResultProxy, OTOH, doesn't attempt to editorialize what comes back from the cursor, so in the case of oracle you get upper case names (these are acceptable to use as keys for row['somekey']). While we maybe could try to connect the original select() statement's SQLA-encoded column names back to the cursor.description's keys and return them as defined on the SQLAlchemy side, you'd still get the uppercase names when we didn't have that information, like execute(select * from table). I have a vague recollection of someone having a specific issue with that behavior but I'm not finding what it was at the moment. On Sep 29, 2008, at 10:04 AM, Itamar Ravid wrote: Hey guys - I've ran into a strange bug in 0.4.7p1 while trying to make use of Elixir's versioned plugin. In Oracle, given a table created as such: CREATE TABLE books (book_id NUMBER PRIMARY KEY); The following code fails: dbEng = create_engine(oracle://:@pearl) meta = MetaData() meta.bind = dbEng booksTable = Table(books, meta, autoload=True) booksTable.insert({'BOOK_ID': 200}).execute() Whilst the following, succeeds: booksTable.insert({'book_id': 200}).execute() This is strange, considering the fact that the following: result = booksTable.select().execute().fetchone() print result.keys() ... results in the column names in uppercase. Am I doing anything wrong? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Declarative and common fields
On Mon, Sep 29, 2008 at 5:01 PM, Joril [EMAIL PROTECTED] wrote: Hi everyone! I'm new to SQLAlchemy and I'm using version 0.5rc1.. I need every entity class to have a few common fields, so I tried writing an abstract base class, declarative-style, that every other entity class would subclass. So for example: --- from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, String, DateTime, Integer ORMBase = declarative_base() class BaseObject(ORMBase): id = Column(Integer, primary_key=True) creation_time = Column(DateTime) modify_time = Column(DateTime) class TestEntity(BaseObject): value = Column(String) --- But SQLAlchemy complains that sqlalchemy.exc.ArgumentError: Mapper 'Mapper|BaseObject|None' does not have a mapped_table specified. (Are you using the return value of table.create()? It no longer has a return value.) Is there a way to tell SQLAlchemy to treat BaseObject like a non- mapped-class? I tried using ORMBase as mixin to TestEntity (so BaseObject extends object and TestEntity extends BaseObject and ORMBase), but now I get a sqlalchemy.exc.ArgumentError: Mapper Mapper|TestEntity|tests could not assemble any primary key columns for mapped table 'tests' so I guess that maybe I'm going down the wrong road.. Am I doing something that Declarative doesn't like? :) Should I try Elixir instead? I don't know whether this is currently possible with Declarative or not. In the case it isn't, patching Declarative should be quite easy (but I don't know if such a patch would be accepted or not). If you don't want to go down that route, Elixir does support that pattern. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Versioning
On Fri, Sep 12, 2008 at 4:37 AM, Sam [EMAIL PROTECTED] wrote: One of the things I really liked about sqlobject was its versioning plug-in. ( http://www.sqlobject.org/Versioning.html ) Is there anything similar for sqlalchemy? A google search turned up versioned ( http://elixir.ematia.de/apidocs/elixir.ext.versioned.html ) This is a plug-in for elixir, but I'm not using elixir. Could I make it work without having to use elixir? Are there other alternatives? Not sure what's it worth but this might be what you are looking for: http://www.okfn.org/vdm/ -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: SQLite Foreign Key Triggers: how to extend sqlalchemy to generate them
On Wed, Aug 27, 2008 at 3:21 AM, Randy Syring [EMAIL PROTECTED] wrote: Ok, so I was going to try and implement a solution using the method discussed here, but ran into a problem b/c I am using Elixir objects and not declaring the tables directly. Can I still use this method? How do I get the table references from the Elixir objects? YourEntity.table After running setup_all(), and obviously before running create_all() or similar (metadata.create_all(), etc...). -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: declarative
On Thu, Aug 21, 2008 at 2:06 PM, Jim Jones [EMAIL PROTECTED] wrote: On Tue, 2008-08-19 at 16:16 -0400, Michael Bayer wrote: On Aug 19, 2008, at 4:07 PM, Gaetan de Menten wrote: Simpler than Elixir? How so? If you are speaking about the internal guts, then you are right declarative is simpler (which is normal since it does less), but if you meant the usage (and I *think* it's what the original poster meant here), I have to disagree... Their simplicity is comparable, and I would even vote for Elixir as slightly simpler because of the little helper methods you get for free... If you meant usage here, please explain why you think so. As far as declarative being simpler I would say, source code wise, architecture wise, things-that-can-go-wrong-wise (i.e., an configurational error message in Elixir can be an elixir problem, or a SQLA problem, or both, its hard to trace), as well as that you only have to learn one paradigm, not two, in order to use it. Though on the last point perhaps Elixir is finally getting to the point where you really don't need to know SQLA configuration in order to use it. Just another datapoint: me too. I started out with elixir but soon switched to declarative because too many times I shot myself in the foot with the subtle differences/interactions between elixir and SA. Furthermore pretty much all SA documentation you can find is in pure SA-speak. I found it easier to convert that to declarative-speak than to elixir-speak because declarative is closer to the real thing. That's true... to some extent. Once you get that all arguments to relation can be also passed to the different Elixir relationships, and column arguments passed to Field, translating SA-speak to Elixir-speak becomes trivial. IMHO elixir is a two-bladed sword. If you know that your task at hand is very simple (and will stay that way) then it can help you with the syntactic sugar. These days, Elixir can handle almost any situation that SA can handle. The only limitation that will never be overcome by Elixir, (but neither by declarative) is to be able to map one class several times (to different selectables). Everyone else will eventually grow out of it. That's quite a bold claim... Ok, Elixir is not your style, that's fine. Also, Elixir certainly doesn't suit every project out there, I'm aware of that. But implying it's not worth it for anybody is well... uninformed. Just don't bash something you probably don't really know. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Elixir 0.6.1 released!
I am very pleased to announce that version 0.6.1 of Elixir (http://elixir.ematia.de) is now available. As always, feedback is very welcome, preferably on Elixir mailing list. This is a minor release featuring some bug fixes (one of them to handle a late rename in SQLAlchemy's 0.5 beta cycle), a new, slighty nicer, syntax for providing custom arguments to the column(s) needed for ManyToOne relationships and some exception messages improvements. The full list of changes can be seen at: http://elixir.ematia.de/trac/browser/elixir/tags/0.6.1/CHANGES What is Elixir? - Elixir is a declarative layer on top of the SQLAlchemy library. It is a fairly thin wrapper, which provides the ability to create simple Python classes that map directly to relational database tables (this pattern is often referred to as the Active Record design pattern), providing many of the benefits of traditional databases without losing the convenience of Python objects. Elixir is intended to replace the ActiveMapper SQLAlchemy extension, and the TurboEntity project but does not intend to replace SQLAlchemy's core features, and instead focuses on providing a simpler syntax for defining model objects when you do not need the full expressiveness of SQLAlchemy's manual mapper definitions. Mailing list http://groups.google.com/group/sqlelixir/about -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Elixir 0.6.0 released!
I am very pleased to announce that version 0.6.0 of Elixir (http://elixir.ematia.de) is now available. As always, feedback is very welcome, preferably on Elixir mailing list. Please look at: http://elixir.ematia.de/trac/wiki/Migrate05to06 for detailed upgrade notes. Here are the highlights for this release: - Added support for SQLAlchemy 0.5 - Better support for entities spread across several modules: in relationship definitions, you don't have to use the full path to the other entity anymore. - Changed the default session characteristics to be more inline with SQLAlchemy defaults (if you were using the default session, please look at those upgrade notes!). - New methods on the base entity to update entities from or dump entities to a hierarchical (JSON-like) dictionary structure. It also features a bunch of bugfixes, mostly related to non-default schema and autoloaded entities. The full list of changes can be seen at: http://elixir.ematia.de/trac/browser/elixir/tags/0.6.0/CHANGES What is Elixir? - Elixir is a declarative layer on top of the SQLAlchemy library. It is a fairly thin wrapper, which provides the ability to create simple Python classes that map directly to relational database tables (this pattern is often referred to as the Active Record design pattern), providing many of the benefits of traditional databases without losing the convenience of Python objects. Elixir is intended to replace the ActiveMapper SQLAlchemy extension, and the TurboEntity project but does not intend to replace SQLAlchemy's core features, and instead focuses on providing a simpler syntax for defining model objects when you do not need the full expressiveness of SQLAlchemy's manual mapper definitions. Mailing list http://groups.google.com/group/sqlelixir/about -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Polymorphic association woes
Hi list, Could anybody tell me what's wrong with the following code? It's only the code in the poly_assoc example directory (the generic version) where I'm trying to set the polymorphic part of the relationship. It gets me the traceback below and I don't really understand why: Traceback (most recent call last): File poly_assoc_3.py, line 155, in module sess.save(u2) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/util.py, line 1550, in func_with_warning return func(*args, **kwargs) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/session.py, line 1055, in save self._cascade_save_or_update(state, entity_name) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/session.py, line , in _cascade_save_or_update self._save_or_update_impl(state) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/session.py, line 1251, in _save_or_update_impl self._update_impl(state) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/session.py, line 1241, in _update_impl session. % (mapperutil.state_str(state), state.key)) sqlalchemy.exc.InvalidRequestError: Could not update instance '[EMAIL PROTECTED]', identity key (class '__main__.GenericAssoc', (1,), None); a different instance with the same identity key already exists in this session. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~--- poly_assoc_3.py Description: application/python
[sqlalchemy] Re: Polymorphic association woes
On Thu, Jul 3, 2008 at 6:01 PM, [EMAIL PROTECTED] wrote: On Thursday 03 July 2008 17:15:40 Michael Bayer wrote: the first set of operations on the Session place every new object, including two Address objects and two GenericAssoc objects, in the session. Then the session is cleared. Then, a series of loads load in all those same objects, including the same Address objects and GenericAssoc objects, except different instances of them local to that session (since the previous were cleared). Then, when u2 = User() is created and is associated with a2 from the *first* session, the two original GenericAssoc objects (which were cleared) now become associated with that User object via the connection to Address, which fail to be added since there are already two GenericAssoc's from the second Session usage present. Jeeez. I hate myself for thinking it was some complex thing related to the pattern used and not even looking further... ahh yes i had this same a week ago but i forgot. so is u2=session.merge(u2) a cure? i used it on some similar (test) case a2 = sess.merge(a2) is a cure indeed. On Jul 3, 2008, at 9:31 AM, Gaetan de Menten wrote: Hi list, Could anybody tell me what's wrong with the following code? It's only the code in the poly_assoc example directory (the generic version) where I'm trying to set the polymorphic part of the relationship. It gets me the traceback below and I don't really understand why: Traceback (most recent call last): File poly_assoc_3.py, line 155, in module sess.save(u2) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/util.py, line 1550, in func_with_warning return func(*args, **kwargs) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/ session.py, line 1055, in save self._cascade_save_or_update(state, entity_name) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/ session.py, line , in _cascade_save_or_update self._save_or_update_impl(state) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/ session.py, line 1251, in _save_or_update_impl self._update_impl(state) File /home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/ session.py, line 1241, in _update_impl session. % (mapperutil.state_str(state), state.key)) sqlalchemy.exc.InvalidRequestError: Could not update instance '[EMAIL PROTECTED]', identity key (class '__main__.GenericAssoc', (1,), None); a different instance with the same identity key already exists in this session. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Operations on instance identity criterion with Many-to-Many self-relational table
On Fri, Jun 27, 2008 at 2:44 PM, MuTPu4 [EMAIL PROTECTED] wrote: I have table wordforms and WordformMapping associated with it. Bi- directional self-relation is expressed by using association table with attributes named infinitives and forms. I am using Elixir for mapping definition so I cannot access association table with it's columns explicitly. FWIW, you can... Assuming the following class: class A(Entity): aa = ManyToMany('A') A.aa.property.secondary gets you to the association table -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Item count along object results
Hi list, Is there really no easier/nicer way to get a count of items alongside object results than the one described at: http://www.sqlalchemy.org/docs/05/ormtutorial.html#datamapping_joins_subqueries ? from sqlalchemy.sql import func stmt = session.query(Address.user_id, func.count('*').label('address_count')).group_by(Address.user_id).subquery() for u, count in session.query(User, stmt.c.address_count).\ ... outerjoin((stmt, User.id==stmt.c.user_id)).order_by(User.id): ... print u, count === I thought something simpler using a subquery instead of a outer join on a subquery would work... But I couldn't make it work. [I'm no expert at SQL optimization but I'd believe the speed should be similar]. session.query(User, select([func.count('*')], User.id == Address.user_id).as_scalar()) It doesn't seem to correlate correctly: no from clause... I think similar queries work (or at least used to) in column_properties?!?. I had to add the manual correlate clause: session.query(User, select([func.count('*')], User.id == Address.user_id).correlate(users).as_scalar()) but even then it doesn't yield any result through the ORM. The generated query yields the correct results in the DB command-line interface though. So I guess it's the ORM part which cannot load it back correctly. It might be related to the fact that the generated query is: SELECT user.[...], (SELECT count(?) AS count_1 FROM backend_blogpost WHERE backend_blog.user = backend_blogpost.blog_user) AS anon_1 FROM backend_blog, backend_blogpost Notice the unnecessary backend_blogpost at the end. Is it a bug, or am I doing something wrong/missing something to get the query right? On a related note, I'm dreaming that something like this would be supported: for u, count in session.query(User, User.addresses.count()): ... print u, count -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Object is already attached to session
On Thu, Jun 12, 2008 at 4:58 PM, bollwyvl [EMAIL PROTECTED] wrote: I am running into similar problems, adding to the complexity the threadpool module. Here's a post that might help: http://blog.uxpython.com/blog/web/view/116 I am still running into problems, however, based on parent/child relationships... i think the answer lies in the sqlalchemy `cascade` property, but I as yet have not found a way to modify that directly in the Elixir layer. I'm not sure the cascade property is the answer to Matt's problem but in any case, you can use the cascade argument on Elixir relationships exactly as you do with SQLAlchemy's relation(). In fact any argument not specifically used by Elixir's relationships is forwarded to the relation() construct. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: SQLAlchemy experts wanted
On Fri, May 16, 2008 at 9:23 PM, Jim R. Wilson [EMAIL PROTECTED] wrote: Hi all, SQLAlchemy is a great project and a growing niche. As it becomes even more popular, there will be increasing demand for experts in the field. I am compiling a contact list of SQLAlchemy experts who may be interested in opportunities under the right circumstances. I am not a recruiter - I'm a regular developer who sometimes gets asked for referrals when I'm not personally available. If you'd like to be on my shortlist of go-to experts, please contact me off-list at: [EMAIL PROTECTED] Wouldn't it be useful to have such a list publicly available (such as on the Wiki)? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Concrete inheritance woes
On Mon, Apr 28, 2008 at 10:33 PM, Michael Bayer [EMAIL PROTECTED] wrote: pjoin = polymorphic_union(...) pjoin2 = polymorphic_union(...) employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type) manager_mapper = mapper(Manager, managers_table, inherits=employee_mapper, concrete=True, polymorphic_identity='manager') engineer_mapper = mapper(Engineer, engineers_table, with_polymorphic=('*', pjoin2), polymorphic_on=pjoin2.c.type, inherits=employee_mapper, concrete=True, polymorphic_identity='engineer') hacker_mapper = mapper(Hacker, hackers_table, inherits=engineer_mapper, concrete=True, polymorphic_identity='hacker') This solves nicely my multi-level problem, thanks ! this should in theory also fix the engineers relation on Company. Doesn't seem to. Since I guess it's a bug, I've filed ticket 1018 for this. http://www.sqlalchemy.org/trac/ticket/1018 But as I've said many times (to svil, at least) concrete inheritance is something i havent gotten into much as of yet, largely due to the many inherent issues with it as well as its being a generally unpopular pattern, so there may still be issues with this setup (but let me know, since thats how it should work). Ok, no worries. In any case the unit tests which you were working from (im guessing test/orm/inheritance/concrete.py) should be patched to include this test (i.e. including Hacker, the polymorphic load, as well as the relation). I'll add the working multi-level test this afternoon. I guess you don't want the relation part yet. Assuming it works we should also make sure the 0.5 branch (which isnt called that yet) can handle it too. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Concrete inheritance woes
On Tue, Apr 29, 2008 at 12:11 PM, Gaetan de Menten [EMAIL PROTECTED] wrote: On Mon, Apr 28, 2008 at 10:33 PM, Michael Bayer [EMAIL PROTECTED] wrote: In any case the unit tests which you were working from (im guessing test/orm/inheritance/concrete.py) should be patched to include this test (i.e. including Hacker, the polymorphic load, as well as the relation). I'll add the working multi-level test this afternoon. Done. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Concrete inheritance woes
Hi there, I've been playing with concrete inheritance a bit these days (trying to implement it into Elixir). I've run into several problems, which might be known limitations, but I'd like to know for sure or be shown what I've done wrong... The two problems I get involve a chain of classes inheriting from one another: class C inherits from class B which inherits from class A. The first problem is that I can get a polymorphic load starting from class B. I'd like it to return instances of class C, along with the instances from class B. Querying class A works as expected though (return instances of A, B and C). See multi_level_concrete.py for what I tried. (It's a hacked/standalone version of the unit tests found in SA itself). FWIW, I run them with nosetest. The second (probably related) problem is that I can't get relationships to work polymorphically. I'd like to have a relationship to the B class. Since I've read in the doc that the relation is not inherited automatically, I tried duplicating manually, but then it doesn't work polymorphically... Anyway, see concrete_with_relations.py for my experimentations. Thanks in advance for any pointer on this, -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~--- from sqlalchemy import * from sqlalchemy.orm import * metadata = MetaData('sqlite:///') companies = Table('companies', metadata, Column('id', Integer, primary_key=True), Column('name', String(50))) managers_table = Table('managers', metadata, Column('employee_id', Integer, primary_key=True), Column('name', String(50)), Column('manager_data', String(50)), Column('company_id', Integer, ForeignKey('companies.id')) ) engineers_table = Table('engineers', metadata, Column('employee_id', Integer, primary_key=True), Column('name', String(50)), Column('engineer_info', String(50)), Column('company_id', Integer, ForeignKey('companies.id')) ) hackers_table = Table('hackers', metadata, Column('employee_id', Integer, primary_key=True), Column('name', String(50)), Column('engineer_info', String(50)), Column('company_id', Integer, ForeignKey('companies.id')), Column('nickname', String(50)) ) metadata.create_all() #metadata.bind.echo = True def test_relation_1(): class Company(object): def __init__(self, name): self.name = name class Employee(object): def __init__(self, name): self.name = name def __repr__(self): return self.__class__.__name__ + + self.name class Manager(Employee): def __init__(self, name, manager_data): self.name = name self.manager_data = manager_data def __repr__(self): return self.__class__.__name__ + + self.name + + self.manager_data class Engineer(Employee): def __init__(self, name, engineer_info): self.name = name self.engineer_info = engineer_info def __repr__(self): return self.__class__.__name__ + + self.name + + self.engineer_info class Hacker(Engineer): def __init__(self, name, nickname, engineer_info): self.name = name self.nickname = nickname self.engineer_info = engineer_info def __repr__(self): return self.__class__.__name__ + + self.name + ' + \ self.nickname + ' + self.engineer_info pjoin = polymorphic_union({ 'manager':managers_table, 'engineer':engineers_table, 'hacker':hackers_table }, 'type', 'pjoin') mapper(Company, companies, properties={ 'engineers':relation(Engineer, lazy=False, enable_typechecks=False) }) employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type) manager_mapper = mapper(Manager, managers_table, inherits=employee_mapper, concrete=True, polymorphic_identity='manager') engineer_mapper = mapper(Engineer, engineers_table, inherits=employee_mapper, concrete=True, polymorphic_identity='engineer', properties={'company': relation(Company)}) hacker_mapper = mapper(Hacker, hackers_table, inherits=engineer_mapper, concrete=True, polymorphic_identity='hacker', properties={'company': relation(Company)}) session = create_session() c = Company('Super') session.save(Manager('Tom', 'knows how to manage things')) c.engineers.append(Engineer('Jerry', 'knows how to program')) c.engineers.append(Hacker('Kurt', 'Badass', 'knows how to hack')) assert
[sqlalchemy] Elixir 0.5.2 released!
I am very pleased to announce that version 0.5.2 of Elixir (http://elixir.ematia.de) is now available. As always, feedback is very welcome, preferably on Elixir mailing list. This is a minor bug fixes release (mostly restoring python 2.3 compatibility). The full list of changes can be seen at: http://elixir.ematia.de/trac/browser/elixir/tags/0.5.2/CHANGES What is Elixir? - Elixir is a declarative layer on top of the SQLAlchemy library. It is a fairly thin wrapper, which provides the ability to create simple Python classes that map directly to relational database tables (this pattern is often referred to as the Active Record design pattern), providing many of the benefits of traditional databases without losing the convenience of Python objects. Elixir is intended to replace the ActiveMapper SQLAlchemy extension, and the TurboEntity project but does not intend to replace SQLAlchemy's core features, and instead focuses on providing a simpler syntax for defining model objects when you do not need the full expressiveness of SQLAlchemy's manual mapper definitions. Mailing list http://groups.google.com/group/sqlelixir/about -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Query for an empty to_many relationship?
Hello all, I'm puzzled as I cannot seem to do a pretty simple query: I have a many to many relationship (say from Vendor to Item) and want to get a list of all vendors which have no item. The obvious: Vendor.query.filter(Vendor.items == []).all() does not work (it produce a query without any where clause). Also, Vendor.items.count doesn't exist. It would be nice if we could express things like: Vendor.query.filter(Vendor.items.count() == 0).all() Maybe I'm just not awake yet, but can someone enlighten me how to do that? On a related note, I've seen the following block in the documentation (in the Relation Operators section): # locate an address sql address = session.query(Address).\ ...filter(Address.email_address=='[EMAIL PROTECTED]').one() ['[EMAIL PROTECTED]'] # use the address in a filter_by expression sql session.query(User).filter_by(addresses=address).all() Is it a simple mistake in the docs or is it really valid? In the later case, shouldn't [collection attribute == single instance] be an invalid case since the new contains, has and any operators appeared? Or is filter_by(x=y) not always equal to CurrentJoinPoint.x == y ? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Elixir 0.5.1 released!
I am very pleased to announce that version 0.5.1 of Elixir (http://elixir.ematia.de) is now available. As always, feedback is very welcome, preferably on Elixir mailing list. This is mostly a bug fixes release (especially for people using inheritance), but we have also a few minor new features, including a new plugin for managing entities as (ordered) lists, enhanced support for custom base classes and an alternate (nicer) syntax to define synonym properties. The full list of changes can be seen at: http://elixir.ematia.de/trac/browser/elixir/tags/0.5.1/CHANGES What is Elixir? - Elixir is a declarative layer on top of the SQLAlchemy library. It is a fairly thin wrapper, which provides the ability to create simple Python classes that map directly to relational database tables (this pattern is often referred to as the Active Record design pattern), providing many of the benefits of traditional databases without losing the convenience of Python objects. Elixir is intended to replace the ActiveMapper SQLAlchemy extension, and the TurboEntity project but does not intend to replace SQLAlchemy's core features, and instead focuses on providing a simpler syntax for defining model objects when you do not need the full expressiveness of SQLAlchemy's manual mapper definitions. Mailing list http://groups.google.com/group/sqlelixir/about -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: odd question
On Jan 23, 2008 10:24 PM, Monty Taylor [EMAIL PROTECTED] wrote: This may or may not be elixir specific... If I have an auto-generated mapping table for a many-to-many relationship, is there a sensible way to add another column to it that's also has a foreign key relationship to a third table? Like, if I had this: Products id int name varchar ProductTypes id int name varchar Groups id int name varchar and then I defined a many to many between products and groups to get products_groups product_id group_id and I wanted to add producttype_id to that ... You'll probably want to use the Association Object pattern, as described at: http://www.sqlalchemy.org/docs/04/mappers.html#advdatamapping_relation_patterns_association And possibly, the AssociationProxy plugin, at: http://www.sqlalchemy.org/docs/04/plugins.html#plugins_associationproxy This one can be used with Elixir just fine. You just need to import it from SQLAlchemy: from sqlalchemy.ext.associationproxy import AssociationProxy -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: a way to share Session.mapper(SomeObject) across two scoped sessions?
On Jan 25, 2008 9:18 PM, Michael Bayer [EMAIL PROTECTED] wrote: On Jan 25, 2008, at 2:02 PM, Kumar McMillan wrote: On Jan 25, 2008 11:58 AM, Michael Bayer [EMAIL PROTECTED] wrote: The Session.mapper function is not worth it, in my opinion, it exists due to the sheer popularity of its previous incarnation, assign_mapper. I much prefer keeping things explicit. I can understand that. I am trying to get this working for an application that has its entire model declared in Elixir already. I like how easy Elixir is and so I'd rather not abandon that layer. But, there is probably a way to configure Elixir for save_on_init=False, I will give it a go. You can provide your own session (configured as you wish) to Elixir. Only the default provided session (it's there for your convenience only but you can perfectly not use it) use Session.mapper (and hence the save_on_init thing). elixir shouldn't be dependent on Session.mapper, if it is, I would advise the elixir folks change that requirement ASAP. in my view, at this point elixir should be for mapper configuration only; after that it should hand off to straight SQLAlchemy for normal runtime operation with any kind of Session configuration; else its just getting in the way. As I said above, it is not anymore (it used to be dependent on assign_mapper), but I changed it to support any kind of session (in version 0.3 I think). The only thing, is that we still provide a default session, which is based on Session.mapper, for convenience and backward compatibility. Maybe we should state more prominently in the Elixir doc that this is only a default session and that you can use any session you like. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: 0.4 deprecation warnings, what is the new get_by/select_by?
On Dec 20, 2007 8:50 AM, iain duncan [EMAIL PROTECTED] wrote: Sorry if this seems a stupid question, but I thought that Mike had said that in sa0.4, if you used session_context that this User.query.get_by(name='john') was the replacement for the old assign mapper convenience call. But I'm getting deprecation warnings. What should I be doing instead of the (almost as) convenient: User.query.get_by( **kwargs ) User.query.filter_by(**kwargs).first() User.query.select_by( **kwargs ) User.query.filter_by(**kwargs).all() User.query.select() User.query.filter(xxx).all() -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Fwd: [elixir] warnings on exit
Since this is not specific to Elixir and I don't know what could be the problem, I'm forwarding this to the SQLAlchemy list. You can watch that list for the answer (which will hopefully be given) or wait until I forward that answer to the Elixir list. -- Forwarded message -- From: Ryszard Szopa [EMAIL PROTECTED] Date: Dec 13, 2007 5:25 PM Subject: [elixir] warnings on exit To: SQLElixir [EMAIL PROTECTED] Hello all, When my python script using Elixir exits, it outputs a lot of warnings. Like: ... Exception exceptions.TypeError: 'NoneType' object is not callable in bound method InstanceState.__cleanup of sqlalchemy.orm.attributes.InstanceState object at 0x870a22c ignored Exception exceptions.TypeError: 'NoneType' object is not callable in bound method InstanceState.__cleanup of sqlalchemy.orm.attributes.InstanceState object at 0x86fee6c ignored Exception exceptions.TypeError: 'NoneType' object is not callable in bound method InstanceState.__cleanup of sqlalchemy.orm.attributes.InstanceState object at 0x86fedac ignored ... Do you have any idea what can be the reason of this behavior? I cannot really identify any part of my code that should be responsible for it. Thanks in advance, -- Richard -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Elixir 0.5.0 released!
I am very pleased to announce that version 0.5.0 of Elixir (http://elixir.ematia.de) is now available. As always, feedback is very welcome, preferably on Elixir mailing list. This is mostly a bug fixes release, but we have also had some pretty important changes to the default values for options. Please look at http://elixir.ematia.de/trac/wiki/Migrate04to05 for detailed upgrade notes. The full list of changes can be seen at: http://elixir.ematia.de/trac/browser/elixir/tags/0.5.0/CHANGES What is Elixir? - Elixir is a declarative layer on top of the SQLAlchemy library. It is a fairly thin wrapper, which provides the ability to create simple Python classes that map directly to relational database tables (this pattern is often referred to as the Active Record design pattern), providing many of the benefits of traditional databases without losing the convenience of Python objects. Elixir is intended to replace the ActiveMapper SQLAlchemy extension, and the TurboEntity project but does not intend to replace SQLAlchemy's core features, and instead focuses on providing a simpler syntax for defining model objects when you do not need the full expressiveness of SQLAlchemy's manual mapper definitions. Mailing list http://groups.google.com/group/sqlelixir/about -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Fwd: [elixir] sqlite3.OperationalError: Could not decode to UTF-8 column
Anybody knows about this? -- Forwarded message -- From: Mitch [EMAIL PROTECTED] Date: Dec 5, 2007 1:06 AM Subject: [elixir] sqlite3.OperationalError: Could not decode to UTF-8 column To: SQLElixir [EMAIL PROTECTED] Apologies in advance if this should be sent to the SQLAlchemy list instead... I have an SQLite3 database created with SQLElixir. One of the table columns, of type String, is being populated from a file which contains ISO-8859 data. When I try to query all records from the table I get a traceback which ends with: File /Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/sqlalchemy/engine/ base.py, line 1497, in fetchall l = [self._process_row(self, row) for row in self._fetchall_impl()] File /Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/sqlalchemy/engine/ base.py, line 1492, in _fetchall_impl return self.cursor.fetchall() sqlite3.OperationalError: Could not decode to UTF-8 column '[...]' with text [...] If I were using the sqlite3 module directly, an acceptable workaround would be to override the default text factory for the database connection, e.g. conn.text_factory = str. Is there any way to do this via the elixir or sqlalchemy APIs? Is there a better solution? Thanks for the help. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] filter_by VS python properties/descriptors VS composite properties
Hi people, I have some classes with standard python properties which target another python object and also uses several columns in the database. I also got a global factory function to create an instance of that target object out of the value of the columns (the class of that target object can vary). Now, I'd like to use those properties in filter criteria, as so: session.query(MyClass).filter(MyClass.my_prop == value)... session.query(MyClass).filter_by(my_prop_name=value)... I've tried using composite properties for that (passing the factory function instead of a composite class), and it actually works, but I'm a little nervous about it: can I have some bad side effect provided that in *some* cases (but not always) the target object is loaded from the database. I also dislike the fact I have to provide a __composite_values__ on all the possible target classes, while in my case, I would prefer to put that logic on the property side. I'd prefer if I could provide a callable which'd take an instance and output the tuple of values, instead of the method. Would that be considered a valid use case for composite properties or am I abusing the system? I've also tried to simply change those properties to descriptors so that I can override __eq__ on the object returned by accessing the property on the class. This worked fine for filter. But I also want to be able to use filter_by. So, I'd wish that query(Class).filter_by(name=value) would be somehow equal to query(Class).filter(Class.name == value), but it's not. filter_by only accepts MapperProperties and not my custom property. So what do people think? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: filter_by VS python properties/descriptors VS composite properties
On Nov 20, 2007 3:12 PM, Chris M [EMAIL PROTECTED] wrote: I think it's a good idea, if Mike agrees then I will submit a patch to do this later today. (Except MyClass.my_prop and my_prop_name won't be equiv, I never said that's what I wanted. Notice that in my example, i speak about filter and filter_by. you'll have to have whatever your property returns support __eq__) Of course. On Nov 20, 4:37 am, Gaetan de Menten [EMAIL PROTECTED] wrote: Hi people, I have some classes with standard python properties which target another python object and also uses several columns in the database. I also got a global factory function to create an instance of that target object out of the value of the columns (the class of that target object can vary). Now, I'd like to use those properties in filter criteria, as so: session.query(MyClass).filter(MyClass.my_prop == value)... session.query(MyClass).filter_by(my_prop_name=value)... I've tried using composite properties for that (passing the factory function instead of a composite class), and it actually works, but I'm a little nervous about it: can I have some bad side effect provided that in *some* cases (but not always) the target object is loaded from the database. I also dislike the fact I have to provide a __composite_values__ on all the possible target classes, while in my case, I would prefer to put that logic on the property side. I'd prefer if I could provide a callable which'd take an instance and output the tuple of values, instead of the method. Would that be considered a valid use case for composite properties or am I abusing the system? I've also tried to simply change those properties to descriptors so that I can override __eq__ on the object returned by accessing the property on the class. This worked fine for filter. But I also want to be able to use filter_by. So, I'd wish that query(Class).filter_by(name=value) would be somehow equal to query(Class).filter(Class.name == value), but it's not. filter_by only accepts MapperProperties and not my custom property. So what do people think? -- Gaëtan de Mentenhttp://openhex.org -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: filter_by VS python properties/descriptors VS composite properties
On Nov 20, 2007 11:51 AM, svilen [EMAIL PROTECTED] wrote: On Tuesday 20 November 2007 11:37:29 Gaetan de Menten wrote: Hi people, I have some classes with standard python properties which target another python object and also uses several columns in the database. I also got a global factory function to create an instance of that target object out of the value of the columns (the class of that target object can vary). Now, I'd like to use those properties in filter criteria, as so: session.query(MyClass).filter(MyClass.my_prop == value)... session.query(MyClass).filter_by(my_prop_name=value)... I've tried using composite properties for that (passing the factory function instead of a composite class), and it actually works, but I'm a little nervous about it: can I have some bad side effect provided that in *some* cases (but not always) the target object is loaded from the database. I also dislike the fact I have to provide a __composite_values__ on all the possible target classes, while in my case, I would prefer to put that logic on the property side. I'd prefer if I could provide a callable which'd take an instance and output the tuple of values, instead of the method. Would that be considered a valid use case for composite properties or am I abusing the system? I've also tried to simply change those properties to descriptors so that I can override __eq__ on the object returned by accessing the property on the class. This worked fine for filter. But I also want to be able to use filter_by. So, I'd wish that query(Class).filter_by(name=value) would be somehow equal to query(Class).filter(Class.name == value), but it's not. filter_by only accepts MapperProperties and not my custom property. what would query(Class).filter(Class.name == value) mean in the case of plain property? Nothing. But in the case of a descriptor, you can do whatever you want with the class property (as opposed to with a standard property(fget, fset) where you are can only take care of instance values). the Class.name == value would selfconvert to SA.expression? Indeed. That's very easy to do though. then what if the filter_by(**kargs) is simply doing _and( getattr( Class, k) == v for k,v in kargs,items() ) That is exactly what I would need in this case BUT I'm not sure it's a good idea to do it, because I'm not sure it's possible to get that behavior alongside with the joinpoint thing (which is a good thing IMO). And it would certainly break other stuff too, so that's probably not worth the trouble if there is no way to get that behavior in addition to what already exist. i dont understand the _composite bit, why u have to bother with that? Because, that's another way to do what I want, which actually works (contrary to the python property solution which doesn't work in the filter_by scenario) but I'm not sure it's the right way to go. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: filter_by VS python properties/descriptors VS composite properties
On Nov 20, 2007 5:23 PM, Michael Bayer [EMAIL PROTECTED] wrote: On Nov 20, 2007, at 4:37 AM, Gaetan de Menten wrote: I have some classes with standard python properties which target another python object and also uses several columns in the database. I also got a global factory function to create an instance of that target object out of the value of the columns (the class of that target object can vary). Now, I'd like to use those properties in filter criteria, as so: session.query(MyClass).filter(MyClass.my_prop == value)... session.query(MyClass).filter_by(my_prop_name=value)... I've tried using composite properties for that (passing the factory function instead of a composite class), and it actually works, but I'm a little nervous about it: can I have some bad side effect provided that in *some* cases (but not always) the target object is loaded from the database. I also dislike the fact I have to provide a __composite_values__ on all the possible target classes, while in my case, I would prefer to put that logic on the property side. I'd prefer if I could provide a callable which'd take an instance and output the tuple of values, instead of the method. Would that be considered a valid use case for composite properties or am I abusing the system? im not totally understanding the all possible target classes concept here, you're creating classes on the fly ? No, but my property returns object of different classes. Let's call it a polymorphic property. if you are in fact creating new classes on the fly, i dont see whats so hard about tacking on a __composite_values__ to each one as well (i.e. dont you have a single function that is doing the generation ?) I dont understand what put that logic on the property side means otherwise. It means that my property is handled by a class and I'd rather put the __composite_values__ function in that class, than in my several target classes (some of them have nothing to do with the database, so it seems awkward to add a method for that). If you can show me some example code that might help, but I think you probably are abusing the system here and the MapperProperty idea that Chris mentioned is probably the way to go. Yeah, that seemed like an elegant way. I've also tried to simply change those properties to descriptors so that I can override __eq__ on the object returned by accessing the property on the class. This worked fine for filter. But I also want to be able to use filter_by. So, I'd wish that query(Class).filter_by(name=value) would be somehow equal to query(Class).filter(Class.name == value), but it's not. filter_by only accepts MapperProperties and not my custom property. Well the general case of filter_by() and filter() awareness is accomplished via synonym(). the filter() part for synonym() doesnt work yet but we have ticket #801 to address that. this ticket will take the existing Python property and put an InstrumentedAttribute wrapper around it. But in this case you aren't making synonym(), you pretty much want a synonym() that doesn't target any particular column. Indeed. Maybe we could expand ticket #801 to include that, or maybe make some new ticket for this. We'd just have another mapper function thats like synonym() but doesnt actually target a column, it just adds that name to the list of properties. But also, the target property, or something else, would have to provide the MapperProperty interface it as well, like Chris says. So a new kind of MapperPropery would be needed here. Done in ticket #875. Thanks for your reply. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: How to get list of relations
On 10/30/07, Paul Johnston [EMAIL PROTECTED] wrote: Mike, use mapper.get_property(name) and mapper.iterate_properties (). I've considered removing properties as a public accessor since it serves no useful purpose. This doesn't work for me - the following code outputs: [Column('id', Integer(), primary_key=True, nullable=False)] [Column('val', String(length=None,convert_unicode=False))] I can do a test case without Elixir if needed, but I don't think that will change the result. from sqlalchemy import * from elixir import * __metadata__ = MetaData('mssql://./test') class Paj(Entity): val = Field(String) class Bob(Entity): paj = ManyToOne(Paj, primary_key=True, backref='bob') silly = Field(Integer) You are missing a compile call before you can iterate properties. try adding: Paj.mapper.compile() But maybe that should be done automatically in iterate_properties. for a in Paj.mapper.iterate_properties: print a.columns -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: FYI: AutoCode moved to a new repository
I couldn't agree more. I mean: shouldn't the autoload part be integrated into SQLAlchemy reflection capability if it can do more than SQLAlchemy 0.4 currently support (or simply removed if it doesn't do more)? And I fact, I think the formatting part could also be integrated into SQLALchemy proper (in the repr methods of the corresponding objects). The whole autocode project could just boil down do a few-lines script (mainly to take command line options and act accordingly). Ok, this is just my 2c, but I hate to see duplication of work :) On 10/11/07, Paul Johnston [EMAIL PROTECTED] wrote: Hi, It's really good to see this script progressing. BTW, with SA 0.4, this script should be able to work with no database-specific hacks at all. If you're interesting in implementing this, I can explain more. Paul -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Elixir
On 9/20/07, Christine [EMAIL PROTECTED] wrote: Any elixir fans? Any idea on when it will finally be made an extension? Let me know. Not sure. I'd like to answer: When it's ready. But ven when it'll be ready, this might not happen. There would be some positive points to that, but also some negative ones, so I guess we'll have to discuss this with the community for more insight on that issue. PS: Here's a decent resource I like http://elixir.ematia.de/ This is the official Elixir website... ;-) -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Elixir performance
On 9/5/07, Paul Johnston [EMAIL PROTECTED] wrote: data. I did some benchmarks a while back to see how everything stacked up as I was wondering if I was doing everything the hard way (in C++) instead of using SqlAlchemy, etc. TurboEntity is the same as Great work Eric. I am quite surprised at the results. I would have thought ActiveMapper/TurboEntity would only be marginally slower than plain SQLAlchemy. To make this really clear (even though Michael said it already), ActiveMapper, TurboEntity and Elixir are not any slower than SA ORM. What is slower is SA ORM compared to SA SQL layer. In fact, Elixir querying system *is* SQLAlchemy proper. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Elixir performance
On 9/4/07, Acm [EMAIL PROTECTED] wrote: I am trying out Elixir 0.3.0 over SQLAlchemy 0.3.10 in a Python 2.5 environment. Are there any known performance issues with Elixir for CRUD (Create Select Update Delete) commands? Not that I know of. There shouldn't be any overhead (over raw SQLAlchemy) after the initial class initialization phase. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: One To Many Polymorphic Association.
You might be interested by: http://techspot.zzzeek.org/?p=13 (also in the examples directory of SQLAlchemy) On 8/24/07, praddy [EMAIL PROTECTED] wrote: ## from sqlalchemy import * meta = BoundMetaData('sqlite://', echo=False) # Parents table. parents = Table('parents', meta, Column(id, Integer, primary_key=True), Column(data, String(50), nullable=False) ) # Children_1 Table. children_1 = Table('children_1', meta, Column(id, Integer, primary_key=True), Column(data, String(50), nullable=False) ) # Children_2 Table. children_2 = Table('children_2', meta, Column(id, Integer, primary_key=True), Column(data, String(50)) ) # Association Table. # This is a generic table which can relate anything to parent. assoc = Table('assoc', meta, # parents.c.id Column(parent_id, Integer, ForeignKey(parents.c.id)), # associate's id either children_1.c.id or children_2.c.id or any other child. Column(assoc_id, Integer), # Which can be either 'child_1' or 'child_2' for now (can be used for extending children # type, decides which table to look in. Column(assoc_type, String(20)) ) ### I am a novice with respect to sqlalchemy may be RDBMS as well. How would you like to work on this scenario to achieve backwards cascading (may not be the right word) which means when one deletes one specific child from children_1 table (for example), there should not be any association entry, which associates that child to the parent, in the association table as well? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: all() or list() ?
On 8/1/07, Alexandre CONRAD [EMAIL PROTECTED] wrote: I'm realizing that I've been using .list() to query objects. But all the examples in the docs talk about .all(). What's the difference ? Should I switch to .all() rather than .list() ? Will list be deprecated in 0.4 ? Exactly. list() is the old way, all() is the 0.4 way. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Single table inheritance and mapping against a selectable
On 7/28/07, Michael Bayer [EMAIL PROTECTED] wrote: those are fine with me. if someone could add a ticket and/or implement that would be helpful. http://www.sqlalchemy.org/trac/ticket/696 -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: a renaming proposal
On 7/27/07, svilen [EMAIL PROTECTED] wrote: On Friday 27 July 2007 02:45:12 jason kirtland wrote: - Catalog: what is a sqlalchemy's metadata? jason a catalog of tables available in the database. to me it holds everything about the subset of database structure, used in the app. as i have seen, sql-wise the term is metadata. going away from sql? To me it is important. sure, it is not The Metadata of the server. Why not just Table_collection? And, is it _just_ table collection, or there's more to it? Catalog... of what? make it TableCatalog then, or just TableSet? elements are uniq and not ordered... what about DBSchema/Schema/TableSchema - it does match one schema, or no? can u have one metadata over tables from 2+ schemas? As I was reminded on IRC, metadata can hold more than Tables: Gedd IF you go to the trouble to change that, I'd say simply TableCollection zzzeek_ yah except indexes and sequences can be in it too stepz and possibly functions Gedd ok, bad idea then zzzeek_ MetaData is based off of fowler's usage of the word stepz and domains stepz and lots of other things zzzeek_ yeah it coujld have functions and domains someday too zzzeek_ it doesnt really right now -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Single table inheritance and mapping against a selectable
On 7/27/07, Michael Bayer [EMAIL PROTECTED] wrote: On Jul 27, 2007, at 4:03 PM, Gaetan de Menten wrote: so do you just want explicit_columns=True so that no auto-grabbing of columns occurs ? I don't know exactly what I want (or maybe it's just I don't care how it's done). It's just that I found it suboptimal that in some cases the columns you select are embedded in the from clause while what you want is modify what is selected before the from clause, whether this is columns or more complex expressions. -- yeah look, this is how it works. your table has x, y, and z. you set up a mapper. x, y and z all become ColumnPropertys on your mapper, without you doing anything, i.e. no properties dict. if you set up a properties dict, columns which you map explicitly will override the normal x, y, z properties...but the rest just get set up normally. so waht you want is this: mapper(X, table, properties={ 'x':table.c.x, 'y':table.c.y }, explicit_columns=True) which means, set up x and y, but dont go setting up everything else inside of table.c (i.e., no z). Yeah, that's exactly what I want, except the name explicit_columns might not be the best. I'd find it natural to be able to put more complex expressions/properties than simple columns (as in other mappers), and that name would suggest we can't. I'd rather see the opposite principle: something along the lines of map_all_columns=False (though I'm not sold on that particular term). -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Insert through ORM performance (was: Performance question)
[in response to a batch-insert-is-slow complaint on the Elixir list] On 7/19/07, AndCycle [EMAIL PROTECTED] wrote: I don't think db define is the major problem, it could be sqlalchemy's problem, because currently it haven't implement real transaction command in most db implementation, all the do_begin define is bypass, so you won't get any efficient batch db access right now. I'm not sure how much of this is true. I'd like to hear any comment about this by people more knowledgeable than me on that topic. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Query.get with unordered multiple-column-primary-key
On 6/13/07, Roger Demetrescu [EMAIL PROTECTED] wrote: Hi Michael, On 6/13/07, Michael Bayer [EMAIL PROTECTED] wrote: On Jun 13, 2007, at 8:48 AM, Roger Demetrescu wrote: But the use of this function is to ugly to my taste (I know, the give_me_pk_values_in_correct_order is too big here): customer = session.query(Customer).get (Customer.give_me_pk_values_in_correct_order(dict(columnX=3, columnY=4, columnZ=343)) Having to repeat Customer reference twic annoys me... :) its python ! its, there should be only one way to do it, we're taking away map() and reduce() because you already have list comprehensions.theres all kinds of things you might want to pass to get(), how would I know how you want to translate it ? Well, from my understanding, the spirit of get is to fetch something that you already know the primary key for, so supporting them in the form of a dictionary seem pretty natural to me. Indeed different people will have different opinions how things should work In my case, passing a dict() in query.get() was so intuitive to me, that I got a little frustrated when noticed it didn't work ... Same here. If query.get() is smart to deal with a sequence (eg: list or tuple), why it shouldn't be with a mapping ? :) Anyway, a couple of custom utilities functions will definitely do the job here.. Indeed. No worries, I'll survive this... It's not something I come across that often anyway. It just felt natural to be able to do it. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: PROPOSAL: whack query.select(), selectfirst(), selectone(), select_by(), selectfirst_by(), selectone_by(), get_by(), auto-join feature
On 6/12/07, Michael Bayer [EMAIL PROTECTED] wrote: we have, in fact, made a tip of the hat to SAT analogy questions (selecting everything is to all() as selecting just the first row is to: a. scalar() b. first() c. list()[0]). I've already said it earlier but since you didn't comment on that, maybe you didn't see my remark: shouldn't the non-generative aggregate methods be deprecated? I feek it would be much more coherent this way. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Query.get with unordered multiple-column-primary-key
Hi, Anybody knows how I could emulate the behavior of Query.get (ie get the result from the session if possible instead of always fetching from the db) if I have the values for the different columns of the primary as keyword arguments (ie not in the order of the columns of the initial table)? I need a kind of a mix between get_by and get. Any idea? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On 6/2/07, Michael Bayer [EMAIL PROTECTED] wrote: On Jun 2, 2007, at 6:02 AM, Gaetan de Menten wrote: Hmmm, after some more thoughts there is one little aspect of that which bothers me: once you joined to something, you can't add filtering criteria on the initial table/class. This is actually one of the features I disliked about the current code. It might be rare use case but I, for one, like to be able to construct queries in any order, so that I can factor out the common part and store it somewhere then add what is specific at a later point. Here, if the specific part is about the initial table, I'm screwed. Adding a method to just move/reset the joinpoint would solve this, though I find it ugly. Better than nothing though. This would look like this: q = session.query(User).join(['orders', 'items']).filter_by (item_name='foo'). user_query = q.join(['addresses']).filter_by (email_address='[EMAIL PROTECTED]').reset_joinpoint() users = user_query.filter_by(name='Foo').list() yeah i had that idea as well, and yeah its a little ugly. theres also the possiblity of using join(None). let me summarize things that im thinking we do: - we want to go with the joinpoint concept here, where join() starts from the beginning, and join(None)/reset_joinpoint brings it back. I'd personally vote for join(None). Seem pretty logical if join starts from the beginning and doesn't introduce a new method (IMHO there are already too many of them on query objects). join() is used to add a join and also modify the joinpoint of the query, so that you can add more criterion using filter() or filter_by () or others. I think this particuar tweak would probably even be OK to put in the current trunk for release 0.3.8 unless people think its going to create problems...the only backwards-incompatible change being a join() starts from the beginning, not the previous join(). - i think filter_by(['list','of','properties'], **kwargs), i.e. an optional, positional string/list-of-strings argument, should also be present, and it will create the joins and criterion using table aliases, and will not be related to joinpoint at all. apparently django does this, and it would let us define criterion for multiple overlapping paths, such as q.filter_by(['a', 'b, 'c'], d=x).filter_by (['a', 'b', 'e'], d=x). thats something that you cant do with the straight join() alone (but of course you can do with explicit aliases and filter()/select_from()). That'd be pretty nice to have that alias feature, because in that case you could join several times to the same table through different relationships easily. - the auto find me a property behavior is gone. not sure if I want to remove it from select_by() and friends, i think it should probably remain in those in a deprecated state. - ClauseElement support would be removed from filter_by(). you can just use filter() for those. the older _by() methods, which i want to deprecate, would be left alone for backwards compatibility. What do you replace order_by with? - i want to deprecate all the criterion methods that are not filter, i.e. all the selects and most of the gets (except straight get()). selecting from a full statement we can do with query.from_statement (select statement), the argument of which is a select() or a string. deprecating select() and select_by() is to create a single simple interface to query based on the more flexible filter(). but it does mean a bit more typing in many cases. I would hope everyone is OK with that. I'd personally like this but that's probably because I don't use those much. But I think many people are using those so that might be an unpopular move. As such, it would probably deserve a thread on its own, so that people would actually have a chance to react... -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: PROPOSAL: whack query.select(), selectfirst(), selectone(), select_by(), selectfirst_by(), selectone_by(), get_by(), auto-join feature
On 6/3/07, Michael Bayer [EMAIL PROTECTED] wrote: - the methods select(), selectfirst(), selectone(), select_by(), selectfirst_by(), selectone_by() and get_by() would be deprecated. this means they will remain present on the Query object but the documentation would be reorganized to talk only about filter(), filter_by(), list(), scalar(), and a new method called one() which is like scalar() but ensures that only one row was returned. I'm unsure about this but wouldn't one be redundant with scalar and [0]? Couldn't we have only one of either one or scalar (and have the check there) and otherwise let people use [0]. so..whattaya say ? Except from that little tweak, everything sounds great (you knew my opinion already but I couldn't resist saying it again)! -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
IMHO, this solves my use case nicely. It's slightly longer than what I proposed but doesn't reach my internal this_is_too_long_to_type threshold and it's more explicit... So for me it's a +1 for that solution (along with documenting the joinpoint behavior ;-)). On 6/2/07, Michael Bayer [EMAIL PROTECTED] wrote: plus *another* option to think about here, which was actually my first (suppressed) instinct, but now i just saw that Hibernate sort of does this, is to *keep* the joinpoint in and just have the join function reset the joinpoint on each invocation. so, session.query(User).join(['orders', 'items']).filter_by (item_name='foo').join(['addresses']).filter_by (email_address='[EMAIL PROTECTED]').list() at the moment, this seems intuitive to me. but i dont know if itll stay that way. i do like that each method has a single type of argument, as opposed to filter_by(qualifier, **kwargs). -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On 6/2/07, Gaetan de Menten [EMAIL PROTECTED] wrote: IMHO, this solves my use case nicely. It's slightly longer than what I proposed but doesn't reach my internal this_is_too_long_to_type threshold and it's more explicit... So for me it's a +1 for that solution (along with documenting the joinpoint behavior ;-)). Hmmm, after some more thoughts there is one little aspect of that which bothers me: once you joined to something, you can't add filtering criteria on the initial table/class. This is actually one of the features I disliked about the current code. It might be rare use case but I, for one, like to be able to construct queries in any order, so that I can factor out the common part and store it somewhere then add what is specific at a later point. Here, if the specific part is about the initial table, I'm screwed. Adding a method to just move/reset the joinpoint would solve this, though I find it ugly. Better than nothing though. This would look like this: q = session.query(User).join(['orders', 'items']).filter_by(item_name='foo'). user_query = q.join(['addresses']).filter_by(email_address='[EMAIL PROTECTED]').reset_joinpoint() users = user_query.filter_by(name='Foo').list() On 6/2/07, Michael Bayer [EMAIL PROTECTED] wrote: plus *another* option to think about here, which was actually my first (suppressed) instinct, but now i just saw that Hibernate sort of does this, is to *keep* the joinpoint in and just have the join function reset the joinpoint on each invocation. so, session.query(User).join(['orders', 'items']).filter_by (item_name='foo').join(['addresses']).filter_by (email_address='[EMAIL PROTECTED]').list() at the moment, this seems intuitive to me. but i dont know if itll stay that way. i do like that each method has a single type of argument, as opposed to filter_by(qualifier, **kwargs). -- Gaëtan de Menten http://openhex.org -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: assign_mapper query methods
For what it's worth I personally vote to get rid of all those query methods (except query() itself, of course). On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: as it turns out, assign_mapper's monkeypatched methods (and they are all monkeypatched, not sure why you singled out query()) dont conflict with mapped properties since those properties get set up subsequent to the assign_mapper call and replace them. however adding new methods to assign_mapper every release does increase the chances of a regular instance variable getting whacked and breaking an application. so i didnt add filter() because i didnt feel like getting all the bug reports from people who have instance variables called filter, and also because my plan was to do away with *all* the select/filter/etc methods and have everything go through query(). because its hard for me to see how query's interface can develop if we have to worry about every new method name conflicting with the full set of instance variable names for all user-defined classes everywhere. but if we dont think its a problem im certainly not going to hold back assign_mapper from what people want it to be, im just putting out the issues there and you all can decide. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: assign_mapper query methods
On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: On Jun 1, 11:37 am, Christoph Haas [EMAIL PROTECTED] wrote: sooner or later. Am I right that we are just talking of john = session.query(User).get_by(name=john) versus john = User.get_by(name=john) well assign_mapper gives you the *huge* advantage that you can forget about the session in most cases, since its applying a SessionContext to all operations, including construction, etc. thats the reason i find myself using it sometimes, it eliminates the need for all those session.save() operations etc. so User.query().etc is definitely less effort since you dont have to find your session. the elixir crew's +1 on having just query() is compelling since theyre the leading consumers of assignmapper. To get this straight, this was my personal opinion, not the one from the whole elixir crew. The other option which was discussed was to get rid of assignmapper altogether (in favor of defining the methods on our base class so that people can override those in their own classes ). No final decision was taken on this issue yet. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Multiple tables forming one class?
And btw, in case I didn't understand what you wanted and you really wanted to map one class to several tables, you'll find information about that there: http://www.sqlalchemy.org/docs/adv_datamapping.html#advdatamapping_joins On 5/7/07, Gaetan de Menten [EMAIL PROTECTED] wrote: On 5/7/07, Spider [EMAIL PROTECTED] wrote: I'm fairly new to this, and trying to understand the ORM relationship between a class and a table row. In most of the examples in the documentation, there is a one-to-one relationship; a class instance corresponds to a row of a table. In my application, my data falls into a 3-tier structure, represented by tables A, B and C. Each A has zero or more Bs, and each B and zero or more Cs. So, A-B is one-to-many, and B-C is one-to-many. From an application perspective, the only type of entity is a A, the only reason I have Bs and Cs is that SQL tables cannot have repeating columns (my previous database experience is with a non-SQL database that allows repeating data items!). I think of the Bs and Cs as just part of the particular A to which they belong. *If* I understood your point correctly (sorry if it's not the case), I think you are looking for one-to-many relationships to the object itself. This can very well be done. Just remember a one-to-many relationship from A to B is expressed in your table as a foreignkey from B to A ! http://www.sqlalchemy.org/docs/datamapping.html#datamapping_relations_onetomany Now, in Python I can represent all the data for a particular A (ie A+B +C) together in one item, say a nested dictionary. A nested dictionary will probably be quite hard to do with SQLAlchemy alone. My question is, can the SQLAlchemy ORM do this for me - i.e. have a single class A which maps to my 3 tables A,B,C and knows how they are joined? If so, what should my class and table declarations look like (and for bounus points, can I specify the declaration using Elixir). In elixir, what you asked above (again assuming I understood what you wanted) would translate to: class A(Entity): has_field('name', String) # or whatever fields has the table ... belongs_to('parent', of_kind='A') has_many('children', of_kind='A') -- Gaëtan de Menten http://openhex.org -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: How do you get the underlying sql (without executing it) from a Statement or a compiled_statement?
Just use print your_statement_variable Or, if you need it in a variable: str(your_statement_variable) should do the trick. On 4/30/07, vinjvinj [EMAIL PROTECTED] wrote: Is there any way to have sqlalchemy return the sql that it is going to execute without actually executing it? I'm using the statement class. Vineet -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Selectable/subquery for a (scalar) column?
On 4/26/07, Michael Bayer [EMAIL PROTECTED] wrote: On Apr 26, 2007, at 4:40 AM, Gaetan de Menten wrote: - you have an aggregate function there. wheres the GROUP BY ? not just of the main table's columns but any other columns named for eager loads. It's unneeded in my example, and for cases where this would be needed, I think we could easily enhance the StatementProperty so that you can add anything to the parent query: join conditions, etc... how do you select multiple columns, where only one column is used in an aggregate function, and no GROUP BY? The answer is: you don't. This is a subselect. Here is, for example, the query generated for the lazy version: SELECT (SELECT sum(tags.score1 * tags.score2) FROM tags WHERE tags.user_id = users.id) AS user_score, users.id AS users_id, users.name AS users_name FROM users ORDER BY users.id are you using mysql only ? Nope. By the way, the patch I did is buggier than I thought for eager relationships. I thought it broke only for subselects, but the simple statement I provided in my example doesn't work nicely either (because it needlessly joins to the tags table). So the result are correct but it's awfull behind the scene. :) But nevermind the patch I did. I realize now it's pretty much useless. But what about the approach I discussed in my previous mail? (using what is in the relation loaders but without creating the instances) -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Selectable/subquery for a (scalar) column?
Ok, I'm quite a bit stubborn at times, so I implemented this the way I thought because I think it makes much more sense this way. Attached is an experimental (as usual) patch to add a StatementProperty, so that you can define stuff like: mapper(Tag, tags_table, properties={ 'query_score': StatementProperty((tags_table.c.score1 * tags_table.c.score2).label('tag_score'), Float()), }) or even: user_score = select([func.sum(tags_table.c.score1 * tags_table.c.score2)], tags_table.c.user_id == users_table.c.id, scalar=True).label('user_score') mapper(User, users_table, properties={ 'tags': relation(Tag, backref='user', lazy=False), 'query_score': StatementProperty(user_score, Float()), }) I don't see what's wrong with this approach so far. As always, I might not see the big picture... I just hope this will be useful in some way, even if it's not what you envisioned. Some random remarks: - the statement you give must have a label (that seem pretty logical this way though) - you need to manually provide the type of the property you create (seem logical too). In a final patch, we'd probably want to also accept types in their class form (Float and Float()). - it works both for lazy and eagerloads (I struggled quite a bit to get those to work) - subselects pulled from a lazyload don't work though. But I think it should be quite easily fixable. - As always, I'm not attached to the names I've given. On 4/24/07, Michael Bayer [EMAIL PROTECTED] wrote: On Apr 24, 2007, at 4:44 AM, Gaetan de Menten wrote: the next way is to do it almost the same as Jonathan's blog says to do it, except youd map the relation to some intermediary class like Score, and then use AssociationProxy to apply the scalar property to the class. I thought about something like this but it felt sooo hacky I disregarded it quickly. this is probably the least hacky as like i said im probably going to implement a feature that works just like this. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Generative query methods for aggregates.
Here is an experimental patch to add generative aggregate methods on query objects. My use case is that I have a class which is often queried with a sum query, from different places. But those different places usually add a filter on top of that basic query. And since I don't like repeating myself, I wanted a way to factor the common part. Here is some (untested) example: score_query = Query(Tag).sum_clause(tags_table.c.score1 * tags_table.c.score2) fun_score_query = score_query.filter_by(name='fun') [... on another place ...] user_fun_score = fun_score_query.filter_by(user=self).scalar() If you agree with the concept and way to do it, I'd happily complete it for the other aggregates and document it. PS: for such new feature suggestions, do you prefer if I add a ticket directly or if I discuss the thing here first? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~--- generative_aggregate.diff Description: application/text
[sqlalchemy] Re: Selectable/subquery for a (scalar) column?
On 4/24/07, Gaetan de Menten [EMAIL PROTECTED] wrote: On 4/23/07, Michael Bayer [EMAIL PROTECTED] wrote: On Apr 23, 2007, at 3:49 PM, Gaetan de Menten wrote: Hello there, In a mapped object, is there any way to map a scalar attribute to an arbitrary selectable/subquery? Jonathan Ellis demonstrated how to do that for relations on this page: http://spyced.blogspot.com/2007/01/why-sqlalchemy-impresses-me.html I'd like to do that for scalars. I've thought about using a property returning a query, but this still generates one query per user (my mapped object) and I need to do everything in one pass. See attached file for an example of what I'd like to do. I've the feeling it might already be possible but I don't see how. If it's not possible yet, do you have any pointer how I could implement that? there are probably three general ways to do what youre doing there. Thanks for the quick answer! the oldest way is something i did in the zblog demo before SA 0.1 was released, which is that you map to the full query you want: s = select([users_table, func.sum(tags_table.c.score1 * tags_table.c.score2).label('score')], users_table.c.user_id==tags_table.c.user_id, group_by=[c for c in users_table.c]) mapper(User, s) the effect above is that your func() becomes another ColumnProperty. That's what I was looking for. So simple... and I didn't think of it. Damn... Hmmm, on second thought, it's not enough for my needs. I need to be able to defer that column and undefer it per query. I know I could use several mappers with entity_names but since I'll have several such columns, it'll be too much trouble to create an alternate mapper for each and every possible combination of those columns being deferred or not. So I guess I'll need to use the ugly intermediary class solution for now. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Selectable/subquery for a (scalar) column?
Hello there, In a mapped object, is there any way to map a scalar attribute to an arbitrary selectable/subquery? Jonathan Ellis demonstrated how to do that for relations on this page: http://spyced.blogspot.com/2007/01/why-sqlalchemy-impresses-me.html I'd like to do that for scalars. I've thought about using a property returning a query, but this still generates one query per user (my mapped object) and I need to do everything in one pass. See attached file for an example of what I'd like to do. I've the feeling it might already be possible but I don't see how. If it's not possible yet, do you have any pointer how I could implement that? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~--- from sqlalchemy import * metadata = MetaData() users_table = Table('users', metadata, Column('id', Integer, primary_key=True), Column('name', String(16)), ) tags_table = Table('tags', metadata, Column('id', Integer, primary_key=True), Column('user_id', Integer, ForeignKey(users.id)), Column('score1', Float), Column('score2', Float) ) metadata.connect('sqlite:///') metadata.create_all() class User(object): def __init__(self, name): self.name = name @property def score_v1(self): return sum(tag.score for tag in self.tags) @property def score_v2(self): tags = object_session(self).query(Tag).filter_by(user=self) return tags.sum(tags_table.c.score1 * tags_table.c.score2) class Tag(object): def __init__(self, score1, score2): self.score1 = score1 self.score2 = score2 @property def score(self): return self.score1 * self.score2 mapper(Tag, tags_table) mapper(User, users_table, properties={ 'tags': relation(Tag, backref='user'), }) u1 = User('joe') t1 = Tag(5.0, 3.0) t2 = Tag(55.0, 1.0) u1.tags = [t1, t2] u2 = User('bar') t3 = Tag(5.0, 4.0) t4 = Tag(50.0, 1.0) t5 = Tag(15.0, 2.0) u2.tags = [t3, t4, t5] session = create_session() session.save(u1) session.save(u2) session.flush() session.clear() metadata.engine.echo = True print ---v1--- # generates 1 query per user and loads tag objects users = session.query(User).select() for user in users: print user.name, user.score_v1 session.clear() print ---v2--- # generates 1 query per user but doesn't load tag objects users = session.query(User).select() for user in users: print user.name, user.score_v2 # I'd like to do the whole thing in 1 query for all users (and without loading # tag objects) #mapper(tag, tags_table, properties={ #'score': special_column( #tags_table.c.score1 * tags_table.c.score2)}) #ideally, reuse subtotal #score_by_user = select([func.sum(Tag.c.subtotal).label('score')], #score_by_user = select([func.sum(tags_table.c.score1 * # tags_table.c.score2).label('score')], # group_by=[tags_table.c.user_id]) #mapper(User, users_table, properties={ #'tags': relation(tag, backref='user'), #'score': special_column(tags_value_by_user), #}) # I also need to be able to defer/undefer those special columns
[sqlalchemy] Re: order_by on related object attribute?
On 4/19/07, Michael Bayer [EMAIL PROTECTED] wrote: On Apr 19, 2007, at 9:39 AM, Gaetan de Menten wrote: By the way, lately I've been wishing SQLAlchemy would add a column (and possibly its table) automatically to the select clause if I do an order by a column which is not in the currently selected columns. I mean that you could write: query(System).select(System.c.lastseen self.this.week, order_by=[client.c.name]) and it would figure out that the client.c.name is not in the selection, and would add it (or rather would add the join you describe above). I would agree up to the point that the table gets added, which is what happens if you add columns to the SELECT clause of a select; the table gets appended to the FROM clause. Good. but i dont agree in creating JOIN objects automatically with no explicit specification that that's whats desired (as usual, i am open to all sorts of explicit methods of specifications...although we have plenty for specifying join on a relationship at this point). the query above I would express generatively as: query(System).filter(System.c.lastseen self.this.week).order_by (client.c.name).join('clients').list() Maybe it would also be handy to have join() accept a Table as well as a Class argument, and have it figure out the auto-thing in those cases as well. all that is fine with me (since theres no other meaning you could get from join(SomeOtherClass) ). Good too. But would this work in all cases? Even if the class is mapped several times, mapped to an arbitrary selectable and so on? cant we just agree that adding the join automatically is an egregious case of implicit over explicit ? Yes, you are perfectly right, and I fully agree the autojoin part was a pretty stupid suggestion. considering that it is *so* *easy* to join on a relationship now: query(MyClass).join('somerelation').select(table2.c.name=='foo') Yes, [and here I was going to say] but it doesn't solve my order by a related column as a mapper option problem but then suddenly realized that what I want is already possible. Mapping my class against the join between system and client, than using order_by=client.c.name should work, right? Sorry for the trouble. Note that it doesn't change the fact that what you agreed to above still seem like a good idea. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] Filtered one_to_many relationships (Experimental)
On 4/17/07, Michael Bayer [EMAIL PROTECTED] wrote: On Apr 10, 2007, at 10:22 AM, Gaetan de Menten wrote: By the way, should I create a ticket for this? ive created ticket #541 for this, I had already created ticket #531 for this. Sorry for not mentioning it here (I thought you'd see it). Anyway, it can be closed too now :). and implemented a slightly refined version of the patch you provided, including the classmethod as well as a generative method + unit tests for both. I added docs and examples for the generative version, so you can see the use cases i was getting at. it will throw an error if you give it input that makes no sense (i.e. two classes that are unrelated). the pattern looks like (assuming the user-address paradigm) : # without specifying the property session.query(Address).with_parent(someuser).list() # specifying the property session.query(Address).with_parent(someuser, property='addresses').filter_by(email_address='[EMAIL PROTECTED]').list() That's just great! I was going to do it eventually but it seems like you beat me to it ;-). Thanks a lot. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] Filtered one_to_many relationships (Experimental)
On 4/10/07, Michael Bayer [EMAIL PROTECTED] wrote: hm, why is from_attr a classmethod ? Because that way, you don't have to specify the related class at all, and you can specify the parameters as args not kwargs. See my first initial remark: * I've implemented Query.from_attr, instead of adding new keywords to the Query constructor, because I think: Query.from_attr(someuser, 'addresses') looks better, is shorter and is more readable than: Query('Address', instance=someuser, attr_name='addresses') not very consistent with all the other generative methods ? True, but I think it makes more sense this way (see below). can we have a regular generative method as well ? If you really want one, I'll gladly do it, but I don't think it makes sense because that method can possibly change the mapper. So, first I'd need to duplicate part of what is in the __init__ method, which doesn't feel right. And second, I think it could be quite confusing for a user. Imagine that Query(A).from_attr(inst, 'rel') could return instances of B (or whatever class is attached to the relation)... Probably not what you'd expect. So, if we go down that route, it would probably be a good idea to check that the mapper in the cloned query is the same than the one we get from the relation. And by the way, from_attr doesn't sound like a generative method, so if you want it, what about filter_from_attr, or something similar? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] Filtered one_to_many relationships (Experimental)
On 4/11/07, svilen [EMAIL PROTECTED] wrote: is from_attr makeing sense for plain atributes, e.g. integers ot whatever? You got a point here. It doesn't work (or even make sense) on plain attributes. if no, maybe choose something like from_relation Fine with me. or filter_relation or filter_relation_tomany or similar if it is expected to only work over relations - and multiple-instances relations; i.e. it is useless over single pointer-like 1:1 relation - so the name would suggest the proper target-type. It works fine for to_one relations. I'm not sure if anybody will ever use it on such relations, but since it works as expected, I see no reason to artificially constrain the thing to to_many relationships. On Wednesday 11 April 2007 11:50:53 Gaetan de Menten wrote: On 4/10/07, Michael Bayer [EMAIL PROTECTED] wrote: hm, why is from_attr a classmethod ? Because that way, you don't have to specify the related class at all, and you can specify the parameters as args not kwargs. See my first initial remark: * I've implemented Query.from_attr, instead of adding new keywords to the Query constructor, because I think: Query.from_attr(someuser, 'addresses') looks better, is shorter and is more readable than: Query('Address', instance=someuser, attr_name='addresses') not very consistent with all the other generative methods ? True, but I think it makes more sense this way (see below). can we have a regular generative method as well ? If you really want one, I'll gladly do it, but I don't think it makes sense because that method can possibly change the mapper. So, first I'd need to duplicate part of what is in the __init__ method, which doesn't feel right. And second, I think it could be quite confusing for a user. Imagine that Query(A).from_attr(inst, 'rel') could return instances of B (or whatever class is attached to the relation)... Probably not what you'd expect. So, if we go down that route, it would probably be a good idea to check that the mapper in the cloned query is the same than the one we get from the relation. And by the way, from_attr doesn't sound like a generative method, so if you want it, what about filter_from_attr, or something similar? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] Filtered one_to_many relationships (Experimental)
On 3/31/07, Michael Bayer [EMAIL PROTECTED] wrote: On Mar 31, 2007, at 1:17 PM, Gaetan de Menten wrote: That's approximately what I did in my patch with the new params keyword argument, except I only implemented the set operation, not the add operation on the params. Anyway, what can/should I do to get this included? Do you have any advice/pointers on how to do the same for eager attributes? (or will you implement it yourself?) im totally into a series of engine/execution patches/refactorings right now, so for properties that have lazy=False, there is still a LazyLoader strategy there...you should just call property._get_strategy(LazyLoader) in all cases to get at it. In case anybody is interested, here is my patch slightly modified with what you suggest above. Now it works wonders for both lazy and eager relationships. There is something ugly about it though: imports. I have to import the LazyLoader class from the orm.strategies module, but that module imports query, so what I did is import the LazyLoader class inside the from_attr method to avoid a circular import problem. By the way, should I create a ticket for this? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~--- Index: orm/query.py === --- orm/query.py(revision 2493) +++ orm/query.py(working copy) @@ -8,6 +8,7 @@ from sqlalchemy.orm import mapper, class_mapper from sqlalchemy.orm.interfaces import OperationContext, SynonymProperty + __all__ = ['Query', 'QueryContext', 'SelectionContext'] class Query(object): @@ -42,12 +43,36 @@ self._distinct = kwargs.pop('distinct', False) self._offset = kwargs.pop('offset', None) self._limit = kwargs.pop('limit', None) -self._criterion = None +self._criterion = kwargs.pop('criterion', None) +self._params = kwargs.pop('params', {}) self._joinpoint = self.mapper self._from_obj = [self.table] for opt in util.flatten_iterator(self.with_options): opt.process_query(self) + +def from_attr(cls, instance, attr_name): +from sqlalchemy.orm.strategies import LazyLoader + +prop = instance.mapper.props[attr_name] +loader = prop._get_strategy(LazyLoader) + +# the following code is taken from strategies.py +# this gets the values of the columns referenced by the property +# for this specific instance +params = {} +allparams = True +for col, bind in loader.lazybinds.iteritems(): +params[bind.key] = loader.parent.get_attr_by_column(instance, col) +if params[bind.key] is None: +allparams = False +break + +if not allparams: +return None + +return Query(prop.mapper, criterion=loader.lazywhere, params=params) +from_attr = classmethod(from_attr) def _clone(self): q = Query.__new__(Query) @@ -71,6 +96,7 @@ q._from_obj = list(self._from_obj) q._joinpoint = self._joinpoint q._criterion = self._criterion +q._params = self._params return q def _get_session(self): @@ -694,8 +720,10 @@ method, which takes the executed statement's ResultProxy directly. - -result = self.session.execute(self.mapper, clauseelement, params=params) +final_params = self._params.copy() +if params is not None: +final_params.update(params) +result = self.session.execute(self.mapper, clauseelement, params=final_params) try: return self.instances(result, **kwargs) finally:
[sqlalchemy] Re: [PATCH] Filtered one_to_many relationships (Experimental)
On 4/10/07, svilen [EMAIL PROTECTED] wrote: can u give some exampe, how this is supposed to be used (finaly)? as relation and/or directly as Query() Attached is a simple example. The setup is done using Elixir but the actual Query.from_attr usage would be the same with plain SA. If you really need a plain SA example, just ask. On Tuesday 10 April 2007 17:22:45 Gaetan de Menten wrote: On 3/31/07, Michael Bayer [EMAIL PROTECTED] wrote: On Mar 31, 2007, at 1:17 PM, Gaetan de Menten wrote: That's approximately what I did in my patch with the new params keyword argument, except I only implemented the set operation, not the add operation on the params. Anyway, what can/should I do to get this included? Do you have any advice/pointers on how to do the same for eager attributes? (or will you implement it yourself?) im totally into a series of engine/execution patches/refactorings right now, so for properties that have lazy=False, there is still a LazyLoader strategy there...you should just call property._get_strategy(LazyLoader) in all cases to get at it. In case anybody is interested, here is my patch slightly modified with what you suggest above. Now it works wonders for both lazy and eager relationships. There is something ugly about it though: imports. I have to import the LazyLoader class from the orm.strategies module, but that module imports query, so what I did is import the LazyLoader class inside the from_attr method to avoid a circular import problem. By the way, should I create a ticket for this? -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~--- from sqlalchemy import * from elixir import * class A(Entity): has_field('name', String(30)) has_many('b', of_kind='B', lazy=False) class B(Entity): has_field('name', String(30)) has_field('extra', Integer) belongs_to('a', of_kind='A') metadata.connect('sqlite:///') create_all() a1 = A(name='a1') b1 = B(name='b1', a=a1, extra=10) b2 = B(name='b2', a=a1) b3 = B(name='b3', a=a1, extra=5) b4 = B(name='b4', a=a1, extra=4) b5 = B(name='b5', a=a1, extra=7) objectstore.flush() objectstore.clear() #metadata.engine.echo = True a = A.get_by(name='a1') print normal q = Query.from_attr(a, 'b') for b in q: print b.name, b.extra print filtered extra 8 for b in q.filter(B.c.extra 8): print b.name, b.extra print ordered by extra for b in q.order_by(B.c.extra): print b.name, b.extra
[sqlalchemy] Re: FlushError (unsaved, pending instance and is an orphan)
On 4/6/07, George Sakkis [EMAIL PROTECTED] wrote: I'm using SA (with Elixir on top) and I have a parent Entity Ranker that has many children Results; that is, for a Ranker instance rk, rk.results gives its children and for a Result rs, rs.ranker gives its parent. When I add new children by providing the parent to the constructor of the child (rather than appending the child to rk.results) and then try to flush, I get: FlushError: instance Result at (...) is an unsaved, pending instance and is an orphan (is not attached to any parent 'Ranker' instance via that classes' 'results' attribute) Here's a (very) stripped-down version of what I'm doing: ranker = Ranker(...) for score in scores: Result(ranker=ranker, score=score, **kwds).save() session.flush() You shouldn't use .save() on your result instances because Elixir automatically adds new instances of your mapped classes to the thread's session. Or more precisely, Elixir uses the assign_mapper plugin which in turns uses the SessionContextExt mapper extension which does that. And session.flush() looks suspicious too. In Elixir, you usually either flush all pending objects using objectstore.flush() or single instances using instance.flush() I expected that I can create a parent-child link either from parent to child (by appending to ranker.results) or from child to parent (as above), but apparently the latter doesn't seem to work. Is this the case or something else is wrong ? George -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] Filtered one_to_many relationships (Experimental)
On 3/26/07, Michael Bayer [EMAIL PROTECTED] wrote: (and whether that be a .query() or Query() or SelectResults not big difference imo.) i vote Query(). I tried to implement it but I couldn't do it the way I wanted to. The problem is: how do I construct a clause from a clause with bind parameters + a dictionary containing the values for said bind parameters? I've only seen bind parameters resolved at execution time. Is it possible to resolve them earlier? In the attached patch, I used a workaround which is to store the bind parameters in the query itself, and then use them whenever the query is executed. Two remarks: * I've implemented Query.from_attr, instead of adding new keywords to the Query constructor, because I think: Query.from_attr(someuser, 'addresses') looks better, is shorter and is more readable than: Query('Address', instance=someuser, attr_name='addresses') * It only works for lazy attributes. I don't think there is any reason we couldn't make it work for eager attributes, but by looking at the eagerloader code, I couldn't figure how to do it. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~--- Index: orm/query.py === --- orm/query.py(revision 2444) +++ orm/query.py(working copy) @@ -42,12 +42,32 @@ self._distinct = kwargs.pop('distinct', False) self._offset = kwargs.pop('offset', None) self._limit = kwargs.pop('limit', None) -self._criterion = None +self._criterion = kwargs.pop('criterion', None) +self._params = kwargs.pop('params', {}) self._joinpoint = self.mapper self._from_obj = [self.table] for opt in util.flatten_iterator(self.with_options): opt.process_query(self) + +def from_attr(cls, instance, attr_name): +prop = instance.mapper.props[attr_name] +loader = prop.strategy +#TODO: make it work for eager loader too. +# code taken from strategies.py +params = {} +allparams = True +for col, bind in loader.lazybinds.iteritems(): +params[bind.key] = loader.parent.get_attr_by_column(instance, col) +if params[bind.key] is None: +allparams = False +break + +if not allparams: +return None + +return Query(prop.mapper, criterion=loader.lazywhere, params=params) +from_attr = classmethod(from_attr) def _clone(self): q = Query.__new__(Query) @@ -71,6 +91,7 @@ q._from_obj = list(self._from_obj) q._joinpoint = self._joinpoint q._criterion = self._criterion +q._params = self._params return q def _get_session(self): @@ -690,8 +711,10 @@ method, which takes the executed statement's ResultProxy directly. - -result = self.session.execute(self.mapper, clauseelement, params=params) +final_params = self._params.copy() +if params is not None: +final_params.update(params) +result = self.session.execute(self.mapper, clauseelement, params=final_params) try: return self.instances(result, **kwargs) finally:
[sqlalchemy] Re: backref VS relation on both sides
On 3/27/07, Michael Bayer [EMAIL PROTECTED] wrote: didnt get your attachment. Yeah, I forgot it, as usual, but it wasn't very import anyway... but yes, they are different. during a many-to-many flush() operation, the two relationships know to communicate which one actually dealt with the row in the many-to-many table, without it, youll get duplicate association rows. additionally, the automatic management of the bi-directional attribute in Python tends to smooth out operations significantly, although two separate attributes should still work. It seems like my question wasn't clear, sorry about that, but your answer contained what I wanted to know anyway. Just for the record (no need to answer again), what I meant was: is it a bug that these two ways behave differently or is it an intended behavior?. Anyway, thanks for the clarification. On Mar 27, 2007, at 7:40 AM, Gaetan de Menten wrote: Hi list, A while ago, someone came up with a problem on the Elixir list. The problem is that in elixir we force users to define relationships on both sides of the relationship (ie, there is no concept of backref). And I (mistakenly) thought that having two mappers with relations to each other was the same as having one mapper with a relation to the other and a backref, so I didn't define backrefs for those relationships. It seems like, in fact, it's not exactly the same: the difference seem to be with the automatic update of the other attribute (the backref) *even before a flush is done*, as demonstrated at: http://www.sqlalchemy.org/docs/ datamapping.html#datamapping_relations_backreferences Now the question is: shouldn't these two ways to define relations be equivalent? Attached is a test case, demonstrating that the second way doesn't work (in case it can be of any use). BTW: there are several mistakes in the example there. Address = mapper(Address, addresses_table) User = mapper(User, users_table, properties = { 'addresses' : relation(Address, backref='user') } ) should read: mapper(Address, addresses_table) mapper(User, users_table, properties = { 'addresses' : relation(Address, backref='user') } ) and a1.user is user and a2.user is user True should be: a1.user is u and a2.user is u True -- Gaëtan de Menten http://openhex.org -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] Filtered one_to_many relationships (Experimental)
On 3/23/07, Michael Bayer [EMAIL PROTECTED] wrote: OK, this is actually something people have asked for a lot. in the beginning, recently, etc. also for different reasons...i.e. convenience, or performance, etc. So, first off let me start by illustrating how this use case is done right now. Assuming your Address mapper has a backref user to the User mapper, its just: for address in session.query(Address).filter_by(user=someuser).filter (address_table.c.postcode == 5000): print address.street Once again, I discover a better way to do something I did the hard way. But, the join conditions and bind params which have been calculated by LazyLoader are just sitting there, they can be currently pulled out with a little non-API attribute access but Ive no problem with adding some API-level accessors to get at the Query object calculated for a particular property (i.e. what you are using in your patch internally). Yes, please do, that'd probably solve the problem nicely (see below how I see things). now lets look at the way your patch does it. addresses = user.addresses.filter(address_table.c.postcode == 5000) seems easy. right ? remember that user is now in the session. anyone else that queries for user will get that same User instance. but the rest of the app is going to assume normal relationship semantics on that collectionwhich means: How I envisioned things, this wouldn't be a problem, because user.addresses.filter(xxx) would return a new, independant list, which doesn't affect user.addresses, and is not affected if user.addresses has already been accessed or not. This is not what my patch does, I know. Sorry for not explaining this in my first mail. print someaddress in user.addresses # -- FAIL - the address is not present user.addresses.remove(someaddress) # -- ERROR - the address is not present user.addresses.insert(5, someotheraddress) # -- FAIL - the list is incomplete, ordering will be incorrect This is only a matter of getattr and __contains__ triggering init, right? (At least if we exclude the other problems pointed above). session.flush() # -- FAIL - we have to figure out what items were added/removed/unchanged from the collection...but the data's incomplete ! I don't master SQLAlchemy internals but I don't see how that is different from when the collection is complete? so as long as we can agree on the its a read-only thing aspect of this, we're good to go. otherwise you have to define for me how all those mutating operations are going to work (and even then, its additional core complexity im not sure if i can add to my support-load). I'm fine with the readonly aspect of it. What I don't like is the fact you have to create a readonly relation (lazyloader/whatever/...) in advance (ie in your mapper), which is IMHO just a dupe of the normal relation and pollutes the mapper. You'd end up with mappers like this: mapper(SomeClass, table, properties={ 'addresses':relation(Address) 'addresses2':lazyloader(Address) }) which is pretty much as ugly as you can get. On the other hand, I think that combined with a quick way to have predefined filters it might be a nice addition anyway: mapper(SomeClass, table, properties={ 'addresses': relation(Address) 'local_addresses': lazyloader(Address, filter=address.c.postcode==5000) }) But it does in no case replace the dynamic non-polluting use-case I'd like to have. What I had in mind is to reuse normal relations to get a query. It feels much more natural and cleaner to me. And I think the best compromise would be something along the lines of: user.addresses: # use standard relation = read/write user.addresses.filter(XXX): # returns a query = read only the code would probably be cleaner if we did something more explicit like: user.addresses.query # returns the query object that you can filter, etc... though, as a user, I'd prefer the first solution. Wouldn't that be possible? I think it should be. You only need to keep the deferred approach of the InstrumentedList that I demonstrated in my patch, so that the whole list is not fetched before we get the query object, which would ruin the whole idea. Of course it was only a proof-of-concept patch, but I think it should be fixable. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] Filtered one_to_many relationships (Experimental)
And by the way, if you agree with that direction of things, I'd happily work on a patch for the query-on-relation thing. On 3/26/07, Gaetan de Menten [EMAIL PROTECTED] wrote: On 3/23/07, Michael Bayer [EMAIL PROTECTED] wrote: OK, this is actually something people have asked for a lot. in the beginning, recently, etc. also for different reasons...i.e. convenience, or performance, etc. So, first off let me start by illustrating how this use case is done right now. Assuming your Address mapper has a backref user to the User mapper, its just: for address in session.query(Address).filter_by(user=someuser).filter (address_table.c.postcode == 5000): print address.street Once again, I discover a better way to do something I did the hard way. But, the join conditions and bind params which have been calculated by LazyLoader are just sitting there, they can be currently pulled out with a little non-API attribute access but Ive no problem with adding some API-level accessors to get at the Query object calculated for a particular property (i.e. what you are using in your patch internally). Yes, please do, that'd probably solve the problem nicely (see below how I see things). now lets look at the way your patch does it. addresses = user.addresses.filter(address_table.c.postcode == 5000) seems easy. right ? remember that user is now in the session. anyone else that queries for user will get that same User instance. but the rest of the app is going to assume normal relationship semantics on that collectionwhich means: How I envisioned things, this wouldn't be a problem, because user.addresses.filter(xxx) would return a new, independant list, which doesn't affect user.addresses, and is not affected if user.addresses has already been accessed or not. This is not what my patch does, I know. Sorry for not explaining this in my first mail. print someaddress in user.addresses # -- FAIL - the address is not present user.addresses.remove(someaddress) # -- ERROR - the address is not present user.addresses.insert(5, someotheraddress) # -- FAIL - the list is incomplete, ordering will be incorrect This is only a matter of getattr and __contains__ triggering init, right? (At least if we exclude the other problems pointed above). session.flush() # -- FAIL - we have to figure out what items were added/removed/unchanged from the collection...but the data's incomplete ! I don't master SQLAlchemy internals but I don't see how that is different from when the collection is complete? so as long as we can agree on the its a read-only thing aspect of this, we're good to go. otherwise you have to define for me how all those mutating operations are going to work (and even then, its additional core complexity im not sure if i can add to my support-load). I'm fine with the readonly aspect of it. What I don't like is the fact you have to create a readonly relation (lazyloader/whatever/...) in advance (ie in your mapper), which is IMHO just a dupe of the normal relation and pollutes the mapper. You'd end up with mappers like this: mapper(SomeClass, table, properties={ 'addresses':relation(Address) 'addresses2':lazyloader(Address) }) which is pretty much as ugly as you can get. On the other hand, I think that combined with a quick way to have predefined filters it might be a nice addition anyway: mapper(SomeClass, table, properties={ 'addresses': relation(Address) 'local_addresses': lazyloader(Address, filter=address.c.postcode==5000) }) But it does in no case replace the dynamic non-polluting use-case I'd like to have. What I had in mind is to reuse normal relations to get a query. It feels much more natural and cleaner to me. And I think the best compromise would be something along the lines of: user.addresses: # use standard relation = read/write user.addresses.filter(XXX): # returns a query = read only the code would probably be cleaner if we did something more explicit like: user.addresses.query # returns the query object that you can filter, etc... though, as a user, I'd prefer the first solution. Wouldn't that be possible? I think it should be. You only need to keep the deferred approach of the InstrumentedList that I demonstrated in my patch, so that the whole list is not fetched before we get the query object, which would ruin the whole idea. Of course it was only a proof-of-concept patch, but I think it should be fixable. -- Gaëtan de Menten http://openhex.org -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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
[sqlalchemy] Re: Possible use of pkg_resources plugins?
On 3/26/07, Michael Bayer [EMAIL PROTECTED] wrote: i think using entry points to load in external database dialects is a great idea. though the current six core dialects i think i still want to load via __import__ though since im a big fan of running SA straight out of the source directory (and therefore thered be no entry points for those in that case). For what it's worth it's perfectly possible to use entry points when running the project from its own source directory. I do it all the time, but I'm not sure what is the exact condition for that to work. Simply having in your source directory a directory named anything.egg-info containing an entry_points.txt file seem to be enough. so probably a check via __import__('sqlalchemy.databases') first, then an entry point lookup. does that work ? On Mar 26, 2007, at 11:45 AM, Monty Taylor wrote: Hey all, I wanted to check and see if a patch would be considered (before I spend any time on it) to replace this: return getattr(__import__('sqlalchemy.databases.%s' % self.drivername).databases, self.drivername) from sqlalchemy.engine.url with something using the pkg_resources plugin stuff from setuptools? I ask, because I'm trying to write a new database engine that's a fairly heavy write. (this is the NDB API thing that doesn't use SQL) I'm not touching any code so far that isn't in a single file in the databases dir, but there are a couple of us who are trying to work on the project together. I'd really like to just version control that one file so we don't have to branch the whole sqlalchemy source. I also think it might be nice to be able to distribute a sqlalchemy database engine without having to get it committed to the trunk. HOWEVER - I recognize that no one else might care about either of these things. I don't think it will be a hard patch or one that will be disruptive to the current way of doing things, but I wanted to check if it would be rejected out of hand before I bothered? Thanks! Monty -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] [PATCH] Filtered one_to_many relationships (Experimental)
Hi list, The recent work that Michael has done about bringing SelectResults functionality to Query made me think: what if that allowed me to do what I've always wanted to have ever since I started using ORMs? The thing I've wanted to do is to have one-to-many relations that you can filter when you access them, and it generates the correct query behind the scene without fetching too many rows from the DB. So I dived into the code a bit deeper than I had up until now... In the end, I didn't use the SelectResults stuff at all, but I've managed to come up with a working patch to do what I wanted anyway. The most interesting part of it is the addition of a DeferredInstrumentedList which takes a callable as argument and actually call it only when the list is accessed. This allows to do stuff like that: for address in user.addresses.filter(address_table.c.postcode == 5000): print address.street The patch is quite experimental (I'm pretty sure I broke some stuff). Also, it only includes a proof-of-concept filter method, but it should be almost trivial to add things like: limit, offset, order_by, distinct, list slicing and so on... And anyway, I'm not sure it's the correct way to go. I _think_ the best way to go would be if InstrumentedList would hold a preconfigured query object, that you could alter the same way you can alter the normal query objects, and which would only be executed when one access the list elements. But to get to this point would need a major refactoring of the code while what I've done is pretty simple. I also attach an (Elixir-made) example demonstrating the thing. Michael, if you are interested in this, I'll gladly translate the example into a plain SQLAlchemy unittest. And more generally, if there is anything I can do (within the limits of my knowledge of SQLAlchemy) to get this done the correct way and included into the trunk, please tell me. I'm so thrilled with this new toy, I hope it'll be possible to include it ! :) -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~--- deferred_list_relation.diff Description: application/text from elixir import * class A(Entity): has_field('name', String(30)) has_many('b', of_kind='B') class B(Entity): has_field('name', String(30)) belongs_to('a', of_kind='A') has_field('extra', Integer) metadata.connect('sqlite:///') create_all() a1 = A(name='a1') a2 = A(name='a2') b1 = B(name='b1', a=a1, extra=10) b2 = B(name='b2', a=a2) b3 = B(name='b3', a=a1, extra=5) objectstore.flush() objectstore.clear() metadata.engine.echo = True a = A.get_by(name='a1') print [b.name for b in a.b.filter(B.c.extra 6)]
[sqlalchemy] Re: How to model an odd many-to-many relationship?
On 3/20/07, Mike Kent [EMAIL PROTECTED] wrote: I have a many-to-many relationship between two entities, call them A and B. This is easy enough to model in sqlalchemy using Elixir. However, to complicate things, I need an integer column somewhere called 'priority'. In the relationship between an A and multiple Bs, I want the Bs to be ordered by the value of the 'priority' column. In the relationship between a B and multiple As, the value of 'priority' is irrelevant. The problem is, I don't know what entity needs to have the 'priority' column in it, or how to model this in the relationship between A and B. I thought that maybe the 'priority' column should be in the secondary table that handles the many-to-many relationship between A and B, but I'm not sure how to set that up, and I'm not sure that Elixir can handle that at all. Basically Elixir doesn't handle that case. For now, your only option is to make a separate entity for the intermediary table, which would hold two belongs_to relationships, and use has_many relationships in your existing entities (A and B) to that new entity, instead of using has_and_belongs_to_many relationships. Now on the SQLAlchemy's side, you can either use that solution too, or use an AssociationProxy. See: http://www.sqlalchemy.org/docs/plugins.html#plugins_associationproxy I personally feel the associationproxy should be better integrated into the normal relation function (preferably as an option), but Michael Bayer doesn't agree with me on this. My point is that many-to-many relationship are already doing some kind of associationproxy behind the scenes, so I don't see why you should use an immensely different way to set things up simply because you have extra fields in your intermediary table. As for Elixir, I've been thinking to integrate the associationproxy into the has_and_belongs_to_many relationship for some time now. I'll do it if enough people are interested. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---