Re: [sqlalchemy] Re: [Distutils] inability to pass setup.py command line arguments to dependency setups

2010-05-07 Thread Gaetan de Menten
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

2010-04-11 Thread Gaetan de Menten
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

2010-04-02 Thread Gaetan de Menten
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

2010-03-21 Thread Gaetan de Menten
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

2010-02-10 Thread Gaetan de Menten
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

2010-02-10 Thread Gaetan de Menten
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

2010-02-05 Thread Gaetan de Menten
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.

2010-01-13 Thread Gaetan de Menten
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

2009-11-16 Thread Gaetan de Menten

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

2009-11-15 Thread Gaetan de Menten

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?

2009-10-19 Thread Gaetan de Menten

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?

2009-10-19 Thread Gaetan de Menten

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

2009-10-14 Thread Gaetan de Menten

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

2009-10-14 Thread Gaetan de Menten
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

2009-10-14 Thread Gaetan de Menten

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!

2009-10-01 Thread Gaetan de Menten

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

2009-09-30 Thread Gaetan de Menten

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

2009-09-30 Thread Gaetan de Menten

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

2009-08-05 Thread Gaetan de Menten

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

2009-08-05 Thread Gaetan de Menten

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')

2009-06-02 Thread Gaetan de Menten

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

2009-02-17 Thread Gaetan de Menten

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

2009-02-16 Thread Gaetan de Menten

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

2009-01-28 Thread Gaetan de Menten

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

2008-12-22 Thread Gaetan de Menten

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

2008-12-08 Thread Gaetan de Menten

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

2008-12-04 Thread Gaetan de Menten

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

2008-12-03 Thread Gaetan de Menten
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

2008-12-03 Thread Gaetan de Menten

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

2008-12-03 Thread Gaetan de Menten

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({ })

2008-10-01 Thread Gaetan de Menten

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

2008-09-29 Thread Gaetan de Menten

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

2008-09-12 Thread Gaetan de Menten

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

2008-08-27 Thread Gaetan de Menten

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

2008-08-21 Thread Gaetan de Menten

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!

2008-08-18 Thread Gaetan de Menten

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!

2008-07-22 Thread Gaetan de Menten

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

2008-07-03 Thread Gaetan de Menten
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

2008-07-03 Thread Gaetan de Menten

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

2008-06-27 Thread Gaetan de Menten

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

2008-06-23 Thread Gaetan de Menten

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

2008-06-13 Thread Gaetan de Menten

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

2008-05-19 Thread Gaetan de Menten

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

2008-04-29 Thread Gaetan de Menten

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

2008-04-29 Thread Gaetan de Menten

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

2008-04-28 Thread Gaetan de Menten
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!

2008-03-28 Thread Gaetan de Menten

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?

2008-02-25 Thread Gaetan de Menten

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!

2008-02-07 Thread Gaetan de Menten

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

2008-01-30 Thread Gaetan de Menten

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?

2008-01-30 Thread Gaetan de Menten

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?

2007-12-20 Thread Gaetan de Menten

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

2007-12-13 Thread Gaetan de Menten

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!

2007-12-08 Thread Gaetan de Menten

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

2007-12-05 Thread Gaetan de Menten

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

2007-11-20 Thread Gaetan de Menten

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

2007-11-20 Thread Gaetan de Menten

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

2007-11-20 Thread Gaetan de Menten

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

2007-11-20 Thread Gaetan de Menten

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

2007-10-30 Thread Gaetan de Menten

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

2007-10-12 Thread Gaetan de Menten

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

2007-09-21 Thread Gaetan de Menten

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

2007-09-06 Thread Gaetan de Menten

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

2007-09-04 Thread Gaetan de Menten

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.

2007-08-24 Thread Gaetan de Menten

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() ?

2007-08-01 Thread Gaetan de Menten

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

2007-07-28 Thread Gaetan de Menten

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

2007-07-27 Thread Gaetan de Menten

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

2007-07-27 Thread Gaetan de Menten

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)

2007-07-19 Thread Gaetan de Menten

[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

2007-06-13 Thread Gaetan de Menten

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

2007-06-12 Thread Gaetan de Menten

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

2007-06-12 Thread Gaetan de Menten

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

2007-06-03 Thread Gaetan de Menten

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

2007-06-03 Thread Gaetan de Menten

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

2007-06-02 Thread Gaetan de Menten

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

2007-06-02 Thread Gaetan de Menten

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

2007-06-01 Thread Gaetan de Menten

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

2007-06-01 Thread Gaetan de Menten

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?

2007-05-07 Thread Gaetan de Menten

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?

2007-04-30 Thread Gaetan de Menten

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?

2007-04-26 Thread Gaetan de Menten

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?

2007-04-25 Thread Gaetan de Menten

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.

2007-04-24 Thread Gaetan de Menten
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?

2007-04-24 Thread Gaetan de Menten

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?

2007-04-23 Thread Gaetan de Menten
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?

2007-04-20 Thread Gaetan de Menten

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)

2007-04-17 Thread Gaetan de Menten

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)

2007-04-11 Thread Gaetan de Menten

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)

2007-04-11 Thread Gaetan de Menten

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)

2007-04-10 Thread Gaetan de Menten
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)

2007-04-10 Thread Gaetan de Menten
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)

2007-04-06 Thread Gaetan de Menten

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)

2007-03-30 Thread Gaetan de Menten
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

2007-03-27 Thread Gaetan de Menten

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)

2007-03-26 Thread Gaetan de Menten

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)

2007-03-26 Thread Gaetan de Menten

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?

2007-03-26 Thread Gaetan de Menten

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)

2007-03-23 Thread Gaetan de Menten
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?

2007-03-20 Thread Gaetan de Menten

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



  1   2   >