[sqlalchemy] odd question

2008-01-23 Thread Monty Taylor

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 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: vote for Python - PLEASE!

2007-10-19 Thread Monty Taylor

Daniel Haus wrote:
 Looks like you're frighteningly successful. You're right, python could
 use much more love, but look at this! Obviously the poll is not
 representative anymore, is it...

Yeah - a little skewed there.

On the other hand, the poll wasn't exactly very scientific in the first 
place. Maybe it'll still trick someone into at least making the python 
links on the MySQL website actually work. :)

--~--~-~--~~~---~--~~
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] vote for Python - PLEASE!

2007-10-18 Thread Monty Taylor

Hey everybody,

MySQL has put up a poll on http://dev.mysql.com asking what your primary 
programming language is. Even if you don't use MySQL - please go stick 
in a vote for Python. I'm constantly telling folks that Python needs 
more love, but PHP and Java are kicking our butts...

(I know the world would be a better place if the poll were honest, but 
I'd rather that people got the message that they should do more python 
development work!)

Thanks!
Monty

--~--~-~--~~~---~--~~
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: [MySQL] Checking if commit() is available

2007-06-11 Thread Monty Taylor

Michael Bayer wrote:
 
 On Jun 8, 2007, at 2:17 PM, Andreas Jung wrote:
 

 --On 8. Juni 2007 14:05:39 -0400 Rick Morrison  
 [EMAIL PROTECTED] wrote:

 try:
 t.commit()
 except:
 print 'Holy cow, this database is lame'


 This code is also lame :-) The code should work
 for arbitrary DSNs and swallowing an exception while
 committing is evil, evil, evil.
 
 with a pre-5 version of mysql, it is the lesser evil

Um - transactions have happily been there since 3.23.15. :)

So the best way to do this is to check the db version and see if it's
greater than 3.23.15 or not.

show variables like 'version' will do the trick to get you the
version. If it's later than 3.23.15 you should be fine.

Monty


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

2007-04-24 Thread Monty Taylor

Michael Bayer wrote:
 
 On Apr 24, 2007, at 8:36 PM, Monty Taylor wrote:
 
 When I get into visit_update and look into the  
 update_stmt.whereclause,
 I have a CompoundClause, which contains a single clause, and an AND
 condition, which is cool. But when I look at the clause, I have a  
 column
 and a parameter. If I print column.id and parameter.__dict__, I get:

 id {'shortname': 'testproject_id', 'unique': True, 'type': Integer(),
 'value': None, 'key': 'testproject_id'}

 Why is the value none? Shouldn't we know that project1 has an id of  
 291?
 Do I need to do something in a visitor to fill in the value here that
 I'm not doing? Is it expected that the ExecutionContext provides this
 value from the object in some way?

 
 the value field inside of _BindParamClause, which is what youre  
 looking at there, is optional.  its usually set when you do things like:
 
 mytable.c.somecolumn == 5
 
 because we have a 5 there, it becomes literal(5) which is just  
 _BindParamClause('literal', 5, unique=True).  the 5 is bound to the  
 bind param.
 
 but bind params can just be names, and the values come in with the  
 execute() arguments.  you can also mix both approaches in which case  
 the params sent to execute() override the bind param values.
 
 so im guessing youre looking at the Updates created inside of  
 mapper.save_obj(), which look like, in a simplified way:
 
 u = table.update(col == sql.bindparam('pk_column'))
 
 i.e. bind param with no value.  and then it executes via
 
 u.execute({'pk_column': 291, 'col_1': col1value, 'col_2':  
 col2value ...})

Well, that explains everything. Thanks!

I was about to say I didn't know how to accomplish that... but I think
that, in fact, while writing that I figured it out. :)

Monty

--~--~-~--~~~---~--~~
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] TPC benchmarks

2007-04-02 Thread Monty Taylor

So I'm working on porting a version of the TPC benchmarks to MySQL. I'm
porting some queries by hand when it hit me - SQLAlchemy has already
done this work. So I thought, why not implement the TPC benchmarks in
SQLAlchemy? Then you would have a benchmark that could be run on all the
databases supported from the same code base without porting - and
anything that SA couldn't do from the benchmark's perspective could be a
potential point of SA improvement, either from a features or a query
generation perspective.

Does this sound interesting to anyone? I don't know if I'll get approval
to hack on this for this project, but I think that in the end it's worth
working on anyway. If anyone wants to play, I'll put up code as soon as
I have it.

Monty

--~--~-~--~~~---~--~~
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] Using entry points to load database dialects

2007-04-01 Thread Monty Taylor

Michael Bayer wrote:
 ok anyway, im behind on patches (which i like to test and stuff) so
 ive added ticket 521 to my in queue list.
 
 if youd like to add a short unit test script that would be handy
 (otherwise we might not have test coverage for the setuptools portion
 of the feature).

Ok. I'll put that in my queue. I hate queues.


 On Mar 28, 12:26 pm, Monty Taylor [EMAIL PROTECTED] wrote:
 Michael Bayer wrote:
 dialects can be used on their own without the engine being present
 (such as, to generate SQL), also you can construct an engine passing
 in your own module object which might have been procured from
 somewhere else (or could be a mock object,for example).
 Ok, yes indeed. Those are good reasons. :)

 On Mar 26, 2007, at 11:45 PM, Monty Taylor wrote:
 Always one in every bunch. :)
 I hear what you're saying about the import errors. But does it really
 help to allow work to get done before throwing the error? I would
 think
 you'd want to know right up front if you don't have a driver loaded
 rather then letting a program actually get started up and think you
 can
 write data (think fat client app) only to get a connection exception.
 But I, of course, could be very wrong about this. I am about many
 things...
 Monty
 Michael Bayer wrote:
 yeah i dont like setup.py develop either :)but anyway,  patch is
 good.  one thing i have to nail down though is ticket #480.   the
 main point of that ticket is to cleanly isolate ImportErrors of
 actual DBAPI modules apart from the containing dialect module
 itself.   the dialects are catching all the DBAPI-related
 ImportErrors though so its not necessarily blocking this patch (its
 just they cant report them nicely).
 On Mar 26, 2007, at 1:34 PM, Monty Taylor wrote:
 Michael Bayer 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).
 so probably a check via __import__('sqlalchemy.databases') first,
 then an entry point lookup.  does that work ?
 Here is a patch that implements use of entry points to load
 dialects.
 The largest change is actually adding a get_dialect to replace the
 functionality of get_module, since entry points really want to
 return
 classes, and we only ever use the dialect class from the returned
 module
 anyway...
 This does not break code that I have that loads the mysql
 dialect, and
 it does work with my new code that adds a new dialect - although I
 suppose it's possible it could have broken something I didn't find.
 As a side note, I agree with Gaetan - you can run entry points and
 stuff
 out of the current directory, especially if you use setup.py
 develop ...
 but this code does the entry points second, after a check for the
 module
 the old way.
 Monty
 === modified file 'lib/sqlalchemy/engine/strategies.py'
 --- lib/sqlalchemy/engine/strategies.py2007-02-25 22:44:52 +
 +++ lib/sqlalchemy/engine/strategies.py2007-03-26 17:03:13 +
 @@ -42,16 +42,16 @@
  u = url.make_url(name_or_url)
  # get module from sqlalchemy.databases
 -module = u.get_module()
 +dialect_cls = u.get_dialect()
  dialect_args = {}
  # consume dialect arguments from kwargs
 -for k in util.get_cls_kwargs(module.dialect):
 +for k in util.get_cls_kwargs(dialect_cls):
  if k in kwargs:
  dialect_args[k] = kwargs.pop(k)
  # create dialect
 -dialect = module.dialect(**dialect_args)
 +dialect = dialect_cls(**dialect_args)
  # assemble connection arguments
  (cargs, cparams) = dialect.create_connect_args(u)
 @@ -71,7 +71,7 @@
  raise exceptions.DBAPIError(Connection
 failed, e)
  creator = kwargs.pop('creator', connect)
 -poolclass = kwargs.pop('poolclass', getattr(module,
 'poolclass', poollib.QueuePool))
 +poolclass = kwargs.pop('poolclass', getattr
 (dialect_cls, 'poolclass', poollib.QueuePool))
  pool_args = {}
  # consume pool arguments from kwargs, translating a
 few of the arguments
  for k in util.get_cls_kwargs(poolclass):
 === modified file 'lib/sqlalchemy/engine/url.py'
 --- lib/sqlalchemy/engine/url.py   2007-03-18 22:35:19 +
 +++ lib/sqlalchemy/engine/url.py   2007-03-26 16:47:01 +
 @@ -2,6 +2,7 @@
  import cgi
  import sys
  import urllib
 +import pkg_resources
  from sqlalchemy import exceptions
  Provide the URL object as well as the make_url parsing
 function.
 @@ -69,6 +70,23 @@
  s += '?' + .join([%s=%s % (k, self.query[k]) for
 k in keys])
  return s
 +def get_dialect(self):
 +Return the SQLAlchemy database dialect class
 corresponding to this URL's driver name.
 +dialect=None

[sqlalchemy] Re: [PATCH] Using entry points to load database dialects

2007-03-28 Thread Monty Taylor

Michael Bayer wrote:
 dialects can be used on their own without the engine being present  
 (such as, to generate SQL), also you can construct an engine passing  
 in your own module object which might have been procured from  
 somewhere else (or could be a mock object,for example).

Ok, yes indeed. Those are good reasons. :)


 On Mar 26, 2007, at 11:45 PM, Monty Taylor wrote:
 
 Always one in every bunch. :)

 I hear what you're saying about the import errors. But does it really
 help to allow work to get done before throwing the error? I would  
 think
 you'd want to know right up front if you don't have a driver loaded
 rather then letting a program actually get started up and think you  
 can
 write data (think fat client app) only to get a connection exception.

 But I, of course, could be very wrong about this. I am about many  
 things...

 Monty

 Michael Bayer wrote:
 yeah i dont like setup.py develop either :)but anyway,  patch is
 good.  one thing i have to nail down though is ticket #480.   the
 main point of that ticket is to cleanly isolate ImportErrors of
 actual DBAPI modules apart from the containing dialect module
 itself.   the dialects are catching all the DBAPI-related
 ImportErrors though so its not necessarily blocking this patch (its
 just they cant report them nicely).


 On Mar 26, 2007, at 1:34 PM, Monty Taylor wrote:

 Michael Bayer 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).

 so probably a check via __import__('sqlalchemy.databases') first,
 then an entry point lookup.  does that work ?
 Here is a patch that implements use of entry points to load  
 dialects.
 The largest change is actually adding a get_dialect to replace the
 functionality of get_module, since entry points really want to  
 return
 classes, and we only ever use the dialect class from the returned
 module
 anyway...

 This does not break code that I have that loads the mysql  
 dialect, and
 it does work with my new code that adds a new dialect - although I
 suppose it's possible it could have broken something I didn't find.

 As a side note, I agree with Gaetan - you can run entry points and
 stuff
 out of the current directory, especially if you use setup.py
 develop ...
 but this code does the entry points second, after a check for the
 module
 the old way.

 Monty


 === modified file 'lib/sqlalchemy/engine/strategies.py'
 --- lib/sqlalchemy/engine/strategies.py2007-02-25 22:44:52 +
 +++ lib/sqlalchemy/engine/strategies.py2007-03-26 17:03:13 +
 @@ -42,16 +42,16 @@
  u = url.make_url(name_or_url)

  # get module from sqlalchemy.databases
 -module = u.get_module()
 +dialect_cls = u.get_dialect()

  dialect_args = {}
  # consume dialect arguments from kwargs
 -for k in util.get_cls_kwargs(module.dialect):
 +for k in util.get_cls_kwargs(dialect_cls):
  if k in kwargs:
  dialect_args[k] = kwargs.pop(k)

  # create dialect
 -dialect = module.dialect(**dialect_args)
 +dialect = dialect_cls(**dialect_args)

  # assemble connection arguments
  (cargs, cparams) = dialect.create_connect_args(u)
 @@ -71,7 +71,7 @@
  raise exceptions.DBAPIError(Connection
 failed, e)
  creator = kwargs.pop('creator', connect)

 -poolclass = kwargs.pop('poolclass', getattr(module,
 'poolclass', poollib.QueuePool))
 +poolclass = kwargs.pop('poolclass', getattr
 (dialect_cls, 'poolclass', poollib.QueuePool))
  pool_args = {}
  # consume pool arguments from kwargs, translating a
 few of the arguments
  for k in util.get_cls_kwargs(poolclass):

 === modified file 'lib/sqlalchemy/engine/url.py'
 --- lib/sqlalchemy/engine/url.py   2007-03-18 22:35:19 +
 +++ lib/sqlalchemy/engine/url.py   2007-03-26 16:47:01 +
 @@ -2,6 +2,7 @@
  import cgi
  import sys
  import urllib
 +import pkg_resources
  from sqlalchemy import exceptions

  Provide the URL object as well as the make_url parsing
 function.
 @@ -69,6 +70,23 @@
  s += '?' + .join([%s=%s % (k, self.query[k]) for
 k in keys])
  return s

 +def get_dialect(self):
 +Return the SQLAlchemy database dialect class
 corresponding to this URL's driver name.
 +dialect=None
 +try:
 +  module=getattr(__import__('sqlalchemy.databases.%s' %
 self.drivername).databases, self.drivername)
 +  dialect=module.dialect
 +except ImportError:
 +if sys.exc_info()[2].tb_next is None:
 +  for res in pkg_resources.iter_entry_points
 ('sqlalchemy.databases'):
 +if res.name

[sqlalchemy] Re: Possible use of pkg_resources plugins?

2007-03-26 Thread Monty Taylor

Michael Bayer 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).
 
 so probably a check via __import__('sqlalchemy.databases') first,  
 then an entry point lookup.  does that work ?

Yes. And I think that's the simplest case anyway - no need to load the
pkg_resources stuff if you don't need it.

I'll see if I can hack that together today.

Thanks!
Monty

 
 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

 
 
  


--~--~-~--~~~---~--~~
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] Using entry points to load database dialects

2007-03-26 Thread Monty Taylor
Michael Bayer 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).
 
 so probably a check via __import__('sqlalchemy.databases') first,  
 then an entry point lookup.  does that work ?

Here is a patch that implements use of entry points to load dialects.
The largest change is actually adding a get_dialect to replace the
functionality of get_module, since entry points really want to return
classes, and we only ever use the dialect class from the returned module
anyway...

This does not break code that I have that loads the mysql dialect, and
it does work with my new code that adds a new dialect - although I
suppose it's possible it could have broken something I didn't find.

As a side note, I agree with Gaetan - you can run entry points and stuff
out of the current directory, especially if you use setup.py develop ...
but this code does the entry points second, after a check for the module
the old way.

Monty


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

=== modified file 'lib/sqlalchemy/engine/strategies.py'
--- lib/sqlalchemy/engine/strategies.py	2007-02-25 22:44:52 +
+++ lib/sqlalchemy/engine/strategies.py	2007-03-26 17:03:13 +
@@ -42,16 +42,16 @@
 u = url.make_url(name_or_url)
 
 # get module from sqlalchemy.databases
-module = u.get_module()
+dialect_cls = u.get_dialect()
 
 dialect_args = {}
 # consume dialect arguments from kwargs
-for k in util.get_cls_kwargs(module.dialect):
+for k in util.get_cls_kwargs(dialect_cls):
 if k in kwargs:
 dialect_args[k] = kwargs.pop(k)
 
 # create dialect
-dialect = module.dialect(**dialect_args)
+dialect = dialect_cls(**dialect_args)
 
 # assemble connection arguments
 (cargs, cparams) = dialect.create_connect_args(u)
@@ -71,7 +71,7 @@
 raise exceptions.DBAPIError(Connection failed, e)
 creator = kwargs.pop('creator', connect)
 
-poolclass = kwargs.pop('poolclass', getattr(module, 'poolclass', poollib.QueuePool))
+poolclass = kwargs.pop('poolclass', getattr(dialect_cls, 'poolclass', poollib.QueuePool))
 pool_args = {}
 # consume pool arguments from kwargs, translating a few of the arguments
 for k in util.get_cls_kwargs(poolclass):

=== modified file 'lib/sqlalchemy/engine/url.py'
--- lib/sqlalchemy/engine/url.py	2007-03-18 22:35:19 +
+++ lib/sqlalchemy/engine/url.py	2007-03-26 16:47:01 +
@@ -2,6 +2,7 @@
 import cgi
 import sys
 import urllib
+import pkg_resources
 from sqlalchemy import exceptions
 
 Provide the URL object as well as the make_url parsing function.
@@ -69,6 +70,23 @@
 s += '?' + .join([%s=%s % (k, self.query[k]) for k in keys])
 return s
 
+def get_dialect(self):
+Return the SQLAlchemy database dialect class corresponding to this URL's driver name.
+dialect=None
+try:
+  module=getattr(__import__('sqlalchemy.databases.%s' % self.drivername).databases, self.drivername)
+  dialect=module.dialect
+except ImportError:
+if sys.exc_info()[2].tb_next is None:
+  for res in pkg_resources.iter_entry_points('sqlalchemy.databases'):
+if res.name==self.drivername:
+  dialect=res.load()
+else:
+   raise
+if dialect is not None:
+return dialect
+raise exceptions.ArgumentError('unknown database %r' % self.drivername) 
+  
 def get_module(self):
 Return the SQLAlchemy database module corresponding to this URL's driver name.
 try:

=== modified file 'setup.py'
--- setup.py	2007-03-23 21:33:24 +
+++ setup.py	2007-03-26 17:01:51 +
@@ -10,6 +10,10 @@
 url = http://www.sqlalchemy.org;,
 packages = find_packages('lib'),
 package_dir = {'':'lib'},
+entry_points = { 
+  'sqlalchemy.databases': [
+'%s = sqlalchemy.databases.%s:dialect' % (f,f) for f in 
+  ['sqlite', 'postgres', 'mysql', 'oracle', 'mssql', 'firebird']]},
 license = MIT License,
 long_description = \
 SQLAlchemy is:



[sqlalchemy] Re: [PATCH] Using entry points to load database dialects

2007-03-26 Thread Monty Taylor

Always one in every bunch. :)

I hear what you're saying about the import errors. But does it really
help to allow work to get done before throwing the error? I would think
you'd want to know right up front if you don't have a driver loaded
rather then letting a program actually get started up and think you can
write data (think fat client app) only to get a connection exception.

But I, of course, could be very wrong about this. I am about many things...

Monty

Michael Bayer wrote:
 
 yeah i dont like setup.py develop either :)but anyway,  patch is  
 good.  one thing i have to nail down though is ticket #480.   the  
 main point of that ticket is to cleanly isolate ImportErrors of  
 actual DBAPI modules apart from the containing dialect module  
 itself.   the dialects are catching all the DBAPI-related  
 ImportErrors though so its not necessarily blocking this patch (its  
 just they cant report them nicely).
 
 
 On Mar 26, 2007, at 1:34 PM, Monty Taylor wrote:
 
 Michael Bayer 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).

 so probably a check via __import__('sqlalchemy.databases') first,
 then an entry point lookup.  does that work ?
 Here is a patch that implements use of entry points to load dialects.
 The largest change is actually adding a get_dialect to replace the
 functionality of get_module, since entry points really want to return
 classes, and we only ever use the dialect class from the returned  
 module
 anyway...

 This does not break code that I have that loads the mysql dialect, and
 it does work with my new code that adds a new dialect - although I
 suppose it's possible it could have broken something I didn't find.

 As a side note, I agree with Gaetan - you can run entry points and  
 stuff
 out of the current directory, especially if you use setup.py  
 develop ...
 but this code does the entry points second, after a check for the  
 module
 the old way.

 Monty


 === modified file 'lib/sqlalchemy/engine/strategies.py'
 --- lib/sqlalchemy/engine/strategies.py  2007-02-25 22:44:52 +
 +++ lib/sqlalchemy/engine/strategies.py  2007-03-26 17:03:13 +
 @@ -42,16 +42,16 @@
  u = url.make_url(name_or_url)

  # get module from sqlalchemy.databases
 -module = u.get_module()
 +dialect_cls = u.get_dialect()

  dialect_args = {}
  # consume dialect arguments from kwargs
 -for k in util.get_cls_kwargs(module.dialect):
 +for k in util.get_cls_kwargs(dialect_cls):
  if k in kwargs:
  dialect_args[k] = kwargs.pop(k)

  # create dialect
 -dialect = module.dialect(**dialect_args)
 +dialect = dialect_cls(**dialect_args)

  # assemble connection arguments
  (cargs, cparams) = dialect.create_connect_args(u)
 @@ -71,7 +71,7 @@
  raise exceptions.DBAPIError(Connection  
 failed, e)
  creator = kwargs.pop('creator', connect)

 -poolclass = kwargs.pop('poolclass', getattr(module,  
 'poolclass', poollib.QueuePool))
 +poolclass = kwargs.pop('poolclass', getattr 
 (dialect_cls, 'poolclass', poollib.QueuePool))
  pool_args = {}
  # consume pool arguments from kwargs, translating a  
 few of the arguments
  for k in util.get_cls_kwargs(poolclass):

 === modified file 'lib/sqlalchemy/engine/url.py'
 --- lib/sqlalchemy/engine/url.py 2007-03-18 22:35:19 +
 +++ lib/sqlalchemy/engine/url.py 2007-03-26 16:47:01 +
 @@ -2,6 +2,7 @@
  import cgi
  import sys
  import urllib
 +import pkg_resources
  from sqlalchemy import exceptions

  Provide the URL object as well as the make_url parsing  
 function.
 @@ -69,6 +70,23 @@
  s += '?' + .join([%s=%s % (k, self.query[k]) for  
 k in keys])
  return s

 +def get_dialect(self):
 +Return the SQLAlchemy database dialect class  
 corresponding to this URL's driver name.
 +dialect=None
 +try:
 +  module=getattr(__import__('sqlalchemy.databases.%s' %  
 self.drivername).databases, self.drivername)
 +  dialect=module.dialect
 +except ImportError:
 +if sys.exc_info()[2].tb_next is None:
 +  for res in pkg_resources.iter_entry_points 
 ('sqlalchemy.databases'):
 +if res.name==self.drivername:
 +  dialect=res.load()
 +else:
 +   raise
 +if dialect is not None:
 +return dialect
 +raise exceptions.ArgumentError('unknown database %r' %  
 self.drivername)
 +
  def get_module(self):
  Return the SQLAlchemy database module corresponding to  
 this URL's driver name

[sqlalchemy] Re: don't automatically stringify compiled statements - patch to base.py

2007-03-15 Thread Monty Taylor

On 3/15/07, Michael Bayer [EMAIL PROTECTED] wrote:

 well at least make a full blown patch that doesnt break all the other
 DB's.  notice that an Engine doesnt just execute Compiled objects, it
 can execute straight strings as well.  thats why the dialect's
 do_execute() and do_executemany() take strings - they are assumed to
 go straight to a DBAPI representation.  to take the stringness out
 of Engine would be a large rework to not just Engine but all the
 dialects.

 im surprised the execute_compiled() method works for you at all, as
 its creating a cursor, calling result set metadata off the cursor,
 etc. all these DBAPI things which you arent supporting.  it seems
 like it would be cleaner for you if you werent even going through
 that implementation of it.

Well, I was trying my best to be a good citizen, so I made some
classes that implement all of the methods that the pieces of
execute_compiled seemed to want, faking it for now when I didn't need
it. The semantics of most of the DBAPI map to the NDBAPI fairly well
(it's still all the same underlying db ideas - just no sql strings)

BUT...

 the theme here is that the base Engine is assuming a DBAPI
 underneath.  if you want an Engine that does not assume string
 statements and DBAPI's it might be easier for you to just provide a
 subclass of Engine instead (or go even lower level, subclass
 sqlalchemy.sql.Executor).   either way you can change what
 create_engine() returns by using a new strategy to create_engine(),
 which is actually a pluggable API.  e.g.

This seems like what I really want to try, because you are right,
trying to get this to pretend to be totally DBAPI is going to be not
totally fun. I'll see what trouble I get myself into this way... or
I'll send a patch that changes all the internals. :)

Thanks!

 from sqlalchemy.engine.strategies import DefaultEngineStrategy

 class NDBAPIEngineStrategy(DefaultEngineStrategy):
def __init__(self):
  DefaultEngineStrategy.__init__(self, 'ndbapi')

  def get_engine_cls(self):
  return NDBAPIEngine

 # register the strategy
 NDBAPIEngineStrategy()

 now you connect via:

 create_engine(url, strategy='ndbapi')

 if you want to go one level lower, which i think you do because you
 dont really want pooling or any of that either, you dont even need to
 have connection pooling or anything like thatyou can totally
 override what create_engine() does, have different connection
 parameters, whatever.  just subclass EngineStrategy directly:

 class NDBAPIEngineStrategy(EngineStrategy):
  def __init__(self):
  EngineStrategy.__init__(self, 'ndbapi')
  def create(self, *args, **kwargs):
  # this is some arbitrary set of arguments
  return NDAPIEngine(kwargs.get('connect_string'), kwargs.get
 ('some_other_argument'), new NDBAPIDialect(*args), etc etc)
 # register
 NBAPIEngineStrategy()

 then you just say:

 create_engine(connect_string='someconnectstring',
 some_other_argument='somethingelse', strategy='ndbapi')

 i.e. whatever you want.  create_engine() just passes *args/**kwargs
 through to create() after pulling out the strategy keyword.

 if you dont like having to send over strategy i can add a hook in
 there to look it up on the dialect, so it could be more like
 create_engine('ndbapi://whatever').  but anyway this method would
 mean we wouldnt have to rewrite half of Engine's internals.


 On Mar 14, 2007, at 7:28 PM, Monty Taylor wrote:

 
  Hi - I'd attach this as a patch file, but it's just too darned
  small...
 
  I would _love_ it if we didn't automatically stringify compiled
  statements here in base.py, because there is no way to override this
  behavior in a dialect. I'm working on an NDBAPI dialect to support
  direct access to MySQL Cluster storage, and so I never actually have a
  string representation of the query. Most of the time this is fine, but
  to make it work, I had to have pre_exec do the actual execution,
  because by the time I got to do_execute, I didn't have my real object
  anymore.
 
  I know this would require some other code changes to actually get
  applied - namely, I'm sure there are other places now where the
  statement should be str()'d to make sense.
 
  Alternately, we could add a method to Compiled. (I know there is
  already get_str()) like get_final_query() that gets called in this
  context instead. Or even, although it makes my personal code less
  readable, just call compiled.get_str() here, which is the least
  invasive, but requires non-string queries to override a method called
  get_str() to achieve a purpose that is not a stringification.
 
  Other than this, so far I've actually got the darned thing inserting
  records, so it's going pretty well... other than a whole bunch of test
  code I put in to find out why it wasn't inserting when the problem was
  that I was checking the wrong table... *doh*
 
  Thanks!
  Monty
 
  === modified file 'lib/sqlalchemy/engine/base.py'
  --- lib

[sqlalchemy] Re: don't automatically stringify compiled statements - patch to base.py

2007-03-15 Thread Monty Taylor

YES. This is good stuff.

Thanks again.

On 3/16/07, Monty Taylor [EMAIL PROTECTED] wrote:
 On 3/15/07, Michael Bayer [EMAIL PROTECTED] wrote:
 
  well at least make a full blown patch that doesnt break all the other
  DB's.  notice that an Engine doesnt just execute Compiled objects, it
  can execute straight strings as well.  thats why the dialect's
  do_execute() and do_executemany() take strings - they are assumed to
  go straight to a DBAPI representation.  to take the stringness out
  of Engine would be a large rework to not just Engine but all the
  dialects.
 
  im surprised the execute_compiled() method works for you at all, as
  its creating a cursor, calling result set metadata off the cursor,
  etc. all these DBAPI things which you arent supporting.  it seems
  like it would be cleaner for you if you werent even going through
  that implementation of it.

 Well, I was trying my best to be a good citizen, so I made some
 classes that implement all of the methods that the pieces of
 execute_compiled seemed to want, faking it for now when I didn't need
 it. The semantics of most of the DBAPI map to the NDBAPI fairly well
 (it's still all the same underlying db ideas - just no sql strings)

 BUT...

  the theme here is that the base Engine is assuming a DBAPI
  underneath.  if you want an Engine that does not assume string
  statements and DBAPI's it might be easier for you to just provide a
  subclass of Engine instead (or go even lower level, subclass
  sqlalchemy.sql.Executor).   either way you can change what
  create_engine() returns by using a new strategy to create_engine(),
  which is actually a pluggable API.  e.g.

 This seems like what I really want to try, because you are right,
 trying to get this to pretend to be totally DBAPI is going to be not
 totally fun. I'll see what trouble I get myself into this way... or
 I'll send a patch that changes all the internals. :)

 Thanks!

  from sqlalchemy.engine.strategies import DefaultEngineStrategy
 
  class NDBAPIEngineStrategy(DefaultEngineStrategy):
 def __init__(self):
   DefaultEngineStrategy.__init__(self, 'ndbapi')
 
   def get_engine_cls(self):
   return NDBAPIEngine
 
  # register the strategy
  NDBAPIEngineStrategy()
 
  now you connect via:
 
  create_engine(url, strategy='ndbapi')
 
  if you want to go one level lower, which i think you do because you
  dont really want pooling or any of that either, you dont even need to
  have connection pooling or anything like thatyou can totally
  override what create_engine() does, have different connection
  parameters, whatever.  just subclass EngineStrategy directly:
 
  class NDBAPIEngineStrategy(EngineStrategy):
   def __init__(self):
   EngineStrategy.__init__(self, 'ndbapi')
   def create(self, *args, **kwargs):
   # this is some arbitrary set of arguments
   return NDAPIEngine(kwargs.get('connect_string'), kwargs.get
  ('some_other_argument'), new NDBAPIDialect(*args), etc etc)
  # register
  NBAPIEngineStrategy()
 
  then you just say:
 
  create_engine(connect_string='someconnectstring',
  some_other_argument='somethingelse', strategy='ndbapi')
 
  i.e. whatever you want.  create_engine() just passes *args/**kwargs
  through to create() after pulling out the strategy keyword.
 
  if you dont like having to send over strategy i can add a hook in
  there to look it up on the dialect, so it could be more like
  create_engine('ndbapi://whatever').  but anyway this method would
  mean we wouldnt have to rewrite half of Engine's internals.
 
 
  On Mar 14, 2007, at 7:28 PM, Monty Taylor wrote:
 
  
   Hi - I'd attach this as a patch file, but it's just too darned
   small...
  
   I would _love_ it if we didn't automatically stringify compiled
   statements here in base.py, because there is no way to override this
   behavior in a dialect. I'm working on an NDBAPI dialect to support
   direct access to MySQL Cluster storage, and so I never actually have a
   string representation of the query. Most of the time this is fine, but
   to make it work, I had to have pre_exec do the actual execution,
   because by the time I got to do_execute, I didn't have my real object
   anymore.
  
   I know this would require some other code changes to actually get
   applied - namely, I'm sure there are other places now where the
   statement should be str()'d to make sense.
  
   Alternately, we could add a method to Compiled. (I know there is
   already get_str()) like get_final_query() that gets called in this
   context instead. Or even, although it makes my personal code less
   readable, just call compiled.get_str() here, which is the least
   invasive, but requires non-string queries to override a method called
   get_str() to achieve a purpose that is not a stringification.
  
   Other than this, so far I've actually got the darned thing inserting
   records, so it's going pretty well... other than a whole bunch of test
   code I put

[sqlalchemy] non-sql storage

2006-10-19 Thread Monty Taylor

So this may sound like a crazy question...

If I wanted to implement an interface to a non-SQL based backend (or I
wanted to use a direct API to the db bypassing the SQL layer) is there
an appropriate place to plug such a thing in and if so where? For it
to make sense, I would want to such code in a place that it could take
advantage of the meta-information defined for a class, bypass the sql
generation step, but still expose the right interface to calling code.

Any thoughts?

Monty

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