[sqlalchemy] Re: assign_mapper query methods
I guess it depends how you look at it. To me assign_mapper adds some Query methods and not others; e.g., .select and .count but not .filter . I assume that's because .filter is so new. But in the manual under Generative Query Methods it implies that .select and .filter are parallel; i.e., you can use either one depending on whether you want the results now or you want to modify the query further. With the regular mapper it's easy to switch between the two by merely changing one method name: rslts = ctx.current.query(MyClass).select(...) q = ctx.current.query(MyClass).filter(...) But with assign_mapper they are not parallel and you have to add or delete an otherwise-useless .query() call (useless because it takes no arguments): rslts = MyClass.select(...) q = MyClass.query().filter(...) As the application's needs change, users will frequently have reason to switch between .select style and .filter style.n You've mentioned earlier that you're not fond of Query.select() at all because users confuse it with Table.select(), and recommended .filter(...).list() instead. If people start doing this wholesale there will be a lot of transformations from .select to .filter, and this same issue will come up. At the same time, I share your concern about adding too many methods to the user class, especially since they may someday collide with one of my database columns. I would rather have parallel select/filter than lots of user class methods. I suppose I could just pretend .select() and .count() don't exist, and use .query().select() and .query().filter() and .query().count() instead -- if .query() is going to be documented and supported long term. I can see why it would be a pity to lose .get(). But on the other hand, why should some Query methods be privileged and others not? --Mike On 5/31/07, Michael Bayer [EMAIL PROTECTED] wrote: heres the question. Query gets 10 new methods one day. do we then add 10 methods to assign_mapper() ? must the user class be a total clone of Query ? assign_mapper just bugs me for this reason. hence i like entity.query() better. im not sure which one youre saying you prefer ? On May 31, 5:46 pm, Mike Orr [EMAIL PROTECTED] wrote: What are future plans for the assign_mapper query methods? MyClass.select(...) -- works great. A clear advantage for assign_mapper over the regular mapper. MyClass.filter(...) -- doesn't exist. MyClass.query().filter(...) -- works but is undocumented and requires a convoluted monkeypatch in the source. Not so clear an advantage over the regular mapper because it's so verbose. The third is the one I've found most useful. That way I can have functions that return a Query, and the caller can call .select(), .select(offset=,limit=), or .count() as they wish. -- Mike Orr [EMAIL PROTECTED] -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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: Firebird can't print an insert() statement
johnbraduk Using SQLAlchemy-0.3.7-py2.4 released with Turbogears johnbraduk Traceback (most recent call last): File johnbraduk /var/tmp/sqlatest.py, line 3, in -toplevel- fbdb = johnbraduk create_engine(dbstr) File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/engine/__init__.py, johnbraduk line 154, in create_engine File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/engine/strategies.py, johnbraduk line 66, in create File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/databases/firebird.py, johnbraduk line 130, in create_connect_args TypeError: init() got johnbraduk an unexpected keyword argument 'concurrency_level' johnbraduk Using version of firebird.py added by guest on johnbraduk 03/19/07 Traceback (most recent call last): File johnbraduk /home/john/sqla/sqlatest.py, line 3, in -toplevel- johnbraduk fbdb = create_engine(dbstr) File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/engine/__init__.py, johnbraduk line 154, in create_engine File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/engine/strategies.py, johnbraduk line 58, in create TypeError: unbound method dbapi() johnbraduk must be called with FBDialect instance as first johnbraduk argument (got nothing instead) John johnbraduk On 31 May, 20:47, Michael Bayer johnbraduk [EMAIL PROTECTED] wrote: firebird is a little like a chicken without a head at this point...im applying fixes but have no FB database with which to test on. Unfortunately I'm loosing my time on completely different issues, instead of making some progress with my refresh of the fb dialect :-| I'll try to understand what's is going on, and eventually upload my current version to the relative ticket if the problem isn't there. In the meanwhile, I'm attaching it here, maybe you could give me some feedback: it's currently passing many more tests than the trunk version. I'm really sorry for the state of affaire, first of all for me not being able to dedicate the needed time: too bad my primary customer using FB is focused on other stuff, and I cannot push Python solutions yet :-| ciao, lele. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~--- firebird.py.gz Description: Binary data
[sqlalchemy] Re: calling a stored function
@Michael Bayer Thank you. The issue could not be solved, probably due to database restrictions (e.g. allowing stored procedures to be used only by admin rights, even though SQLAlchemy used an admin type user...seems that the database server recognizes that the call is being made from an external source and although the user has admin rights does not allow it to execute UPDATE queries). I worked around the problem by developing the stored procedure in Python / SQLAlchemy. --~--~-~--~~~---~--~~ 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: Firebird can't print an insert() statement
Michael, Here are the results I am getting. I am trying to get TurboGears to work so I don't know which versions of SQLAlchemy can be used with TG and not screw it up. Test prog. from sqlalchemy import * dbstr = 'firebird://SYSDBA:[EMAIL PROTECTED]/usr/ibdata/eiti61.gdb' fbdb = create_engine(dbstr) Using SQLAlchemy-0.3.7-py2.4 released with Turbogears Traceback (most recent call last): File /var/tmp/sqlatest.py, line 3, in -toplevel- fbdb = create_engine(dbstr) File build/bdist.linux-i686/egg/sqlalchemy/engine/__init__.py, line 154, in create_engine File build/bdist.linux-i686/egg/sqlalchemy/engine/strategies.py, line 66, in create File build/bdist.linux-i686/egg/sqlalchemy/databases/firebird.py, line 130, in create_connect_args TypeError: init() got an unexpected keyword argument 'concurrency_level' Using version of firebird.py added by guest on 03/19/07 Traceback (most recent call last): File /home/john/sqla/sqlatest.py, line 3, in -toplevel- fbdb = create_engine(dbstr) File build/bdist.linux-i686/egg/sqlalchemy/engine/__init__.py, line 154, in create_engine File build/bdist.linux-i686/egg/sqlalchemy/engine/strategies.py, line 58, in create TypeError: unbound method dbapi() must be called with FBDialect instance as first argument (got nothing instead) John On 31 May, 20:47, Michael Bayer [EMAIL PROTECTED] wrote: firebird is a little like a chicken without a head at this point...im applying fixes but have no FB database with which to test on. what results/stack traces/everything else are you getting with the current SQLAlchemy trunk ? On May 31, 2007, at 3:33 PM, johnbraduk wrote: Roger, Please excuse the interrupt, but have you applied other fixes? I (and others) can't event get SQLA to connect to my Firebird v1.5.4 database running on SUSE Linux. John On 30 May, 19:47, Roger Demetrescu [EMAIL PROTECTED] wrote: Michael, the patch did the trick... I was able to print the statement, execute it, and also do some inserts using ORM... Now the second part of my problem, which is not fixed yet... ;) here is the script (now using default value/expression): from datetime import datetime from sqlalchemy import * db = create_engine(firebird://user:[EMAIL PROTECTED]//database.fdb) metadata = BoundMetaData(db) pessoa_table = Table('pessoa', metadata, Column('pes_id', Integer, primary_key=True), Column('pes_data', DateTime, default=func.current_timestamp()), Column('pes_nome', String(30)), Column('pes_sobrenome', String(30)), Column('pes_idade', Integer), Column('pes_idade', Integer)) s = pessoa_table.select() u = pessoa_table.update() i = pessoa_table.insert() Now my shell session : i.execute(pes_id=111, pes_data=datetime.now()) sqlalchemy.engine.base.ResultProxy object at 0x018C0D50 i.execute(pes_id=222) Traceback (most recent call last): File pyshell#11, line 1, in module i.execute(pes_id=222) File d:\sqlalchemy\lib\sqlalchemy\sql.py, line 1175, in execute return self.compile(engine=self.engine, parameters=compile_params).execute(*multiparams, **params) File d:\sqlalchemy\lib\sqlalchemy\sql.py, line 1064, in execute return e.execute_compiled(self, *multiparams, **params) File d:\sqlalchemy\lib\sqlalchemy\engine\base.py, line 783, in execute_compiled return connection.execute_compiled(compiled, *multiparams, **params) File d:\sqlalchemy\lib\sqlalchemy\engine\base.py, line 570, in execute_compiled context.pre_exec() File d:\sqlalchemy\lib\sqlalchemy\engine\default.py, line 200, in pre_exec self._process_defaults() File d:\sqlalchemy\lib\sqlalchemy\engine\default.py, line 303, in _process_defaults newid = drunner.get_column_default(c) File d:\sqlalchemy\lib\sqlalchemy\engine\base.py, line 1234, in get_column_default return column.default.accept_visitor(self) File d:\sqlalchemy\lib\sqlalchemy\schema.py, line 807, in accept_visitor return visitor.visit_column_default(self) File d:\sqlalchemy\lib\sqlalchemy\engine\base.py, line 1275, in visit_column_default return self.exec_default_sql(default) File d:\sqlalchemy\lib\sqlalchemy\databases\firebird.py, line 367, in exec_default_sql c = sql.select([default.arg], from_obj=[rdb$database]).compile(engine=self.engine) AttributeError: 'FBDefaultRunner' object has no attribute 'engine' Now I'm going to explicitly insert a row with pes_data = NULL (should'nt that work ??): i.execute(pes_id=333, pes_data=None) Traceback (most recent call last): File pyshell#12, line 1, in module i.execute(pes_id=333, pes_data=None) File d:\sqlalchemy\lib\sqlalchemy\sql.py, line 1175, in execute return self.compile(engine=self.engine, parameters=compile_params).execute(*multiparams, **params) File
[sqlalchemy] Re: Firebird can't print an insert() statement
FYI I get this trace with the version you attached. Traceback (most recent call last): File /home/john/sqla/sqlatest.py, line 5, in -toplevel- fbdb = create_engine(dbstr) File build/bdist.linux-i686/egg/sqlalchemy/engine/__init__.py, line 154, in create_engine File build/bdist.linux-i686/egg/sqlalchemy/engine/strategies.py, line 66, in create File /home/john/sqla/firebird.py, line 307, in create_connect_args if self.dbapi is not None and not self.dbapi.initialized: AttributeError: 'module' object has no attribute 'initialized' Thanks for your help and I understand that you have other priorities. I am probably doing something wrong, is it correct to copy your firebird.py into the folder with my source and import it? I have also replaced the firebird.py in the .egg and get the same error. To be quite honest I think I will go back to good old simple mod_python and kinterbasdb. Althought TG is a great concept when it doesn't work the poor old appllciation programmer doesn't stand a hope. There are far too many levels of code and dependencies between the enduser and the database! John On 1 Jun, 10:52, Lele Gaifax [EMAIL PROTECTED] wrote: johnbraduk Using SQLAlchemy-0.3.7-py2.4 released with Turbogears johnbraduk Traceback (most recent call last): File johnbraduk /var/tmp/sqlatest.py, line 3, in -toplevel- fbdb = johnbraduk create_engine(dbstr) File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/engine/__init__.py, johnbraduk line 154, in create_engine File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/engine/strategies.py, johnbraduk line 66, in create File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/databases/firebird.py, johnbraduk line 130, in create_connect_args TypeError: init() got johnbraduk an unexpected keyword argument 'concurrency_level' johnbraduk Using version of firebird.py added by guest on johnbraduk 03/19/07 Traceback (most recent call last): File johnbraduk /home/john/sqla/sqlatest.py, line 3, in -toplevel- johnbraduk fbdb = create_engine(dbstr) File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/engine/__init__.py, johnbraduk line 154, in create_engine File johnbraduk build/bdist.linux-i686/egg/sqlalchemy/engine/strategies.py, johnbraduk line 58, in create TypeError: unbound method dbapi() johnbraduk must be called with FBDialect instance as first johnbraduk argument (got nothing instead) John johnbraduk On 31 May, 20:47, Michael Bayer johnbraduk [EMAIL PROTECTED] wrote: firebird is a little like a chicken without a head at this point...im applying fixes but have no FB database with which to test on. Unfortunately I'm loosing my time on completely different issues, instead of making some progress with my refresh of the fb dialect :-| I'll try to understand what's is going on, and eventually upload my current version to the relative ticket if the problem isn't there. In the meanwhile, I'm attaching it here, maybe you could give me some feedback: it's currently passing many more tests than the trunk version. I'm really sorry for the state of affaire, first of all for me not being able to dedicate the needed time: too bad my primary customer using FB is focused on other stuff, and I cannot push Python solutions yet :-| ciao, lele. firebird.py.gz 10KDownload --~--~-~--~~~---~--~~ 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
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. --~--~-~--~~~---~--~~ 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: Problem on autoload with MS-SQL
Patch applied now and wokr like is expected. Thanks --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: assign_mapper query methods
On Fri, Jun 01, 2007 at 07:17:19AM -0700, Michael Bayer wrote: 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(). Right. I didn't think of that possibility. Do I read that as assign_mapper will die anyway because you have an implicit PITA tag on it already? ;) 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. I think I will refrain from using assign_mapper in the future. I'd like to use .filter() because it's great and I'd rather use the explicit mapper syntax instead of the (barely easier) assign_mapper syntax just to be consistent. Sometimes using the assign_mapper because it's simpler but in other places use the mapper methods because they are more powerful doesn't really look consistent. If you asked me: either provide these methods on the assign_mapper, too, or let the assign_mapper die 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) here? I think I can live with that. Inserting/creating new objects looks the same with both mapping methods AFAIK. So we are talking about wasting 15 bytes in every query. I'll go waste some bytes then. Cheers Christoph --~--~-~--~~~---~--~~ 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: Weakly-referenced object error
the latest version of MySQLDB does use weakrefs right at the heart of things, in connections.py and cursors.py.since we are catching the exception we cant see the full original stack trace but its possible that it would trace into mysqldb's source code. that doesnt rule out that we are doing something to cause this to happen in SA, but im pretty sure people are using pool_recycle with mysql successfully. On Jun 1, 1:11 am, Mike Orr [EMAIL PROTECTED] wrote: It happens only when the site has been idle for several hours; i.e. overnight. Once it starts it keeps happening every request until I restart the application. The first time it happened, somebody had gotten a MySQL server has gone away error during the night, followed by a couple weak-reference errors. I noticed that pool_recycle wasn't being passed properly and fixed it. Since then I've gotten weak-reference errors almost every morning, but without the server-gone error. I restart the server and it runs the rest of the day. Today I upgraded from MySQLdb 1.2.0 to 1.2.2 so maybe that will fix it. --Mike On 5/31/07, Michael Bayer [EMAIL PROTECTED] wrote: nothing is weakly referenced within the block where that exception is being thrown. the only place weakrefs are used outside of the ORM is a couple of dictionaries in pool.py. you havent said what reproduces this problem ? you just start the app, and it happens every time ? On May 31, 6:01 pm, Mike Orr [EMAIL PROTECTED] wrote: I've been getting this on my Pylons site. sqlalchemy.exceptions.SQLError: (ReferenceError) weakly-referenced object no longer exists It's trying to execute an ORM .select() call. The first time was after a MySQL server has gone away error, so I assumed some mapped instances had been orphaned. But now I'm still getting it even though I've set .pool_recycle to 1 hour and restarted the application several times. I've got SQLAlchemy 0.3.7 on the server, which is where the error is occuring. My workstation has the trunk version, but I probably don't keep the app running long enough to give this a chance to happen. The full traceback follows. File '/mnt/data/www/apps/inews2/inews/controllers/main.py', line 14 in index c.top = model.list_incidents(top_only=True) File '/mnt/data/www/apps/inews2/inews/models/__init__.py', line 60 in list_incidents return q.select(order_by=order_by, offset=offset, limit=limit) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/orm/query.py', line 319 in select return self.select_whereclause(whereclause=arg, **kwargs) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/orm/query.py', line 326 in select_whereclause return self._select_statement(statement, params=params) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/orm/query.py', line 927 in _select_statement return self.execute(statement, params=params, **kwargs) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/orm/query.py', line 831 in execute result = self.session.execute(self.mapper, clauseelement, params=params) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/orm/session.py', line 183 in execute return self.connection(mapper, close_with_result=True).execute(clause, params, **kwargs) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/engine/base.py', line 509 in execute return Connection.executors[c](self, object, *multiparams, **params) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/engine/base.py', line 549 in execute_clauseelement return self.execute_compiled(elem.compile(dialect=self.dialect, parameters=param), *multiparams, **params) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/engine/base.py', line 560 in execute_compiled self._execute_raw(context) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/engine/base.py', line 573 in _execute_raw self._execute(context) File '/mnt/data/www/apps/inews2/wenv-inews/lib/python2.4/SQLAlchemy-0.3.7-py2.4.egg/sqlalchemy/engine/base.py', line 591 in _execute raise exceptions.SQLError(context.statement, context.parameters, e) SQLError: (ReferenceError) weakly-referenced object no longer exists u'SELECT `IN_Incident`.is_type_other AS `IN_Incident_is_type_other`, `IN_Incident`.measure_shore AS `IN_Incident_measure_shore`, `IN_Incident`.ptl_search_min AS `IN_Incident_ptl_search_min`, `IN_Incident`.measure_burn AS `IN_Incident_measure_burn`, `IN_Incident`.actl_entered_max AS
[sqlalchemy] Re: assign_mapper query methods
For what it's worth I personally vote to get rid of all those query methods (except query() itself, of course). On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: as it turns out, assign_mapper's monkeypatched methods (and they are all monkeypatched, not sure why you singled out query()) dont conflict with mapped properties since those properties get set up subsequent to the assign_mapper call and replace them. however adding new methods to assign_mapper every release does increase the chances of a regular instance variable getting whacked and breaking an application. so i didnt add filter() because i didnt feel like getting all the bug reports from people who have instance variables called filter, and also because my plan was to do away with *all* the select/filter/etc methods and have everything go through query(). because its hard for me to see how query's interface can develop if we have to worry about every new method name conflicting with the full set of instance variable names for all user-defined classes everywhere. but if we dont think its a problem im certainly not going to hold back assign_mapper from what people want it to be, im just putting out the issues there and you all can decide. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Copy Select object
What is the best way for create a clone of Select object except for columns list ? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: assign_mapper query methods
On 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. --~--~-~--~~~---~--~~ 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] probably unsupported type for date field
Hello I am seeing an error when trying to insert a row with a date field into an SQLite database. The error is the same as the problem that has been seen with Decimals on postgres but presumably it's a different issue. I have upgraded my pysqlite to 3.3.17 but that didn't help. Below is the full error and a minimal repro scenario. The problem goes away if you reorder the columns in the table creation code to put the date column last (sadly this doesn't fix the problem in my real code...). I have other tables with date columns that work without any problem. I noticed in the log for inserting rows into those other tables that the date value appears in the SQL as something like '2007-06-01' rather than '(datetime.date(2007, 6, 1),)' as in the error message below. That may be relevant or it may be an artefact of the way the log message is created as opposed to the exception string. I'm running Python 2.5 on Windows with SQLAlchemy 0.3.7. Any ideas what the problem might be? Thanks Ben - Traceback (most recent call last): File C:\cygwin\home\barwork\test.py, line 20, in module session.flush() File build\bdist.win32\egg\sqlalchemy\orm\session.py, line 302, in flush File build\bdist.win32\egg\sqlalchemy\orm\unitofwork.py, line 219, in flush File build\bdist.win32\egg\sqlalchemy\orm\unitofwork.py, line 409, in execute File build\bdist.win32\egg\sqlalchemy\orm\unitofwork.py, line 1027, in execute File build\bdist.win32\egg\sqlalchemy\orm\unitofwork.py, line 1041, in execute_save_steps File build\bdist.win32\egg\sqlalchemy\orm\unitofwork.py, line 1032, in save_objects File build\bdist.win32\egg\sqlalchemy\orm\mapper.py, line 1182, in save_obj File build\bdist.win32\egg\sqlalchemy\engine\base.py, line 509, in execute File build\bdist.win32\egg\sqlalchemy\engine\base.py, line 549, in execute_clauseelement File build\bdist.win32\egg\sqlalchemy\engine\base.py, line 560, in execute_compiled File build\bdist.win32\egg\sqlalchemy\engine\base.py, line 573, in _execute_raw File build\bdist.win32\egg\sqlalchemy\engine\base.py, line 591, in _execute sqlalchemy.exceptions.SQLError: (InterfaceError) Error binding parameter 1 - probably unsupported type. u'INSERT INTO things (date, value) VALUES (?,?)' ['(datetime.date(2007, 6, 1),)', ('asdf',)] from sqlalchemy import * from datetime import date class Thing(object): def __init__(self, date, value): self.date = date, self.value = value, thing_table = Table('things', Column('id', Integer, primary_key=True), Column('date', Date), Column('value', String(10))) mapper(Thing, thing_table) global_connect('sqlite://') default_metadata.create_all() session = create_session() session.save(Thing(date.today(), 'asdf')) session.flush() --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: assign_mapper query methods
On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: On Jun 1, 11:37 am, Christoph Haas [EMAIL PROTECTED] wrote: sooner or later. Am I right that we are just talking of john = session.query(User).get_by(name=john) versus john = User.get_by(name=john) well assign_mapper gives you the *huge* advantage that you can forget about the session in most cases, since its applying a SessionContext to all operations, including construction, etc. thats the reason i find myself using it sometimes, it eliminates the need for all those session.save() operations etc. so User.query().etc is definitely less effort since you dont have to find your session. the elixir crew's +1 on having just query() is compelling since theyre the leading consumers of assignmapper. To get this straight, this was my personal opinion, not the one from the whole elixir crew. The other option which was discussed was to get rid of assignmapper altogether (in favor of defining the methods on our base class so that people can override those in their own classes ). No final decision was taken on this issue yet. -- Gaëtan de Menten http://openhex.org --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: probably unsupported type for date field
youll notice from this: sqlalchemy.exceptions.SQLError: (InterfaceError) Error binding parameter 1 - probably unsupported type. u'INSERT INTO things (date, value) VALUES (?,?)' ['(datetime.date(2007, 6, 1),)', ('asdf',)] both the date and the 'asdf' values are being sent in the form of one- element tuples. this is due to this: class Thing(object): def __init__(self, date, value): self.date = date, self.value = value, which should be: class Thing(object): def __init__(self, date, value): self.date = date self.value = value and all is well. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Jun 1, 2007, at 12:39 PM, Gaetan de Menten wrote: This enables things like so (see attached elixir-based example for more): A.query().filter_by_via('b', name='b2').filter_by_via('c', name='c2') To Michael: I'm ready to document that myself, but I just don't want to do it for nothing in the unlikely event you'd agree with me that this join_point thing should be removed. Another thing which I find ugly in the query class is the whole idea of using a locate property method. It's awfully unreliable: if two properties lead to different classes both having a property with the same name, which one is used? I'd like if people at least had a way to specify the full path leading to the desired property (and still use a concise keyword syntax and not full blown where clauses). well this is all related. id like to take out the auto-descending thing out of filter_by(), *_by(), and join(). but if you take out the joinpoint, *and* the auto-descend thing which is already ambiguous, filter_by and friends become not very useful. like this would not produce the expected results at all: A.foo - B.bar - C.lala query(A).join(['foo', 'bar']).filter_by(lala=5) So id propose something like what you did above, but not use a string, just use the class, and have it as the first optional positional arg to all the _by()s query(A).join(['foo', 'bar']).filter_by(C, lala=5) and we can even bring back a modified version auto-descend in that case: query(A).filter_by(C, lala=5) since above its not ambiguous. another thing i have always wanted to do, is take the ClauseElement stuff out of the _by() methods. I know people put ClauseElements in those but that was because there used to not be a way to mix ClauseElements with keywords...now there is, just call filter() and filter_by() separately. if you agree with all that, lets just put it straight into 0.4. i think we should get a little dramatic here, make the above filtering changes, and also whack all the redundant methods: that is, get_by (), select_by(), select(), selectfirst(), selectone(),selectfirst_by (), etc etcthey get replaced with filter()/filter_by() - list()/ scalar()/one(). this would also eliminate most of the confusion people have from the multiple select() functions produced by different APIs. by whack i havent decided if i mean, whack, or deprecate and remove from main docs. Id go with the latter, but a lot of other tutorial sites and such which have sprang up would have to go with me here and make similar changes to their docselse people will keep using the old methods. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: assign_mapper query methods
On Jun 1, 2007, at 12:46 PM, Gaetan de Menten wrote: 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. -- I like that latter idea too. assignmapper was a hack from day one. good job elixir crew ! ;) --~--~-~--~~~---~--~~ 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
Both session.query(User).select() and User.query().select() seem more verbose than they need to be for my taste. However, I think most people (myself included) define a base class for all their mapped classes. I've always used this base class to provide the interface I want, no matter what interface sqlalchemy provides (and SA's API has changed quite a bit since 0.1). I suppose if anyone is going to pollute the namespace of the User class, it should be me, not sqlalchemy. That said, if I was new to sqlalchemy, I think I'd be scared to see session.query(User).select() as the recommended way in the tutorial. So, +1/2 from me on ditching assign_mapper (while keeping SessionContext, of course). shoe On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: On Jun 1, 2007, at 12:46 PM, Gaetan de Menten wrote: 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. -- I like that latter idea too. assignmapper was a hack from day one. good job elixir crew ! ;) -- --- I'd give my right arm to be ambidextrous. --- --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: assign_mapper query methods
On Fri, Jun 01, 2007 at 10:50:33AM -0700, David Shoemaker wrote: Both session.query(User).select() and User.query().select() seem more verbose than they need to be for my taste. However, I think most people (myself included) define a base class for all their mapped classes. Uhm, that (few) people I know just use assign_mapper as demonstrated in the many tutorials. Even myself. And now that you mention it I like the idea. Not duplicating what SA is providing but rather making your own life easier. I've always used this base class to provide the interface I want, no matter what interface sqlalchemy provides Now I'm curious. Could you share your base class? That said, if I was new to sqlalchemy, I think I'd be scared to see session.query(User).select() as the recommended way in the tutorial. From lurking on IRC I'm sure most people are indeed scared by SA. :) Christoph --~--~-~--~~~---~--~~ 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: Weakly-referenced object error
On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: the latest version of MySQLDB does use weakrefs right at the heart of things, in connections.py and cursors.py.since we are catching the exception we cant see the full original stack trace but its possible that it would trace into mysqldb's source code. that doesnt rule out that we are doing something to cause this to happen in SA, but im pretty sure people are using pool_recycle with mysql successfully. Well, IF the problem does not go away I guess I'll have to restart the application every few hours. But with debug=false an external program can't tell if an Internal Server Error is this or something else, so do I, um, grep the error log? ... Hmm. I could somehow catch the error and deliver a slightly different error message (perhaps using JJ's case-modified headers secret code :), but then I might as well just restart the application... however one might do that within the application. Could I just refresh the connection pool or expire all the connections without disrupting the rest of the application? But I guess all of MySQLdb would need to be reinitialized, wouldn't it. What about a monitor process like --reload: could it somehow be made to know when this error occurs and restart the subprocess if so? Why can't SQLAlchemy catch this and the gone-away error, refresh the connection, and redo the query like SQLObject does? That's really what one wants, not a pool_recycle time. I think you said that's incompatible with transactions but I don't see how. -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Jun 1, 2007, at 1:24 PM, Michael Bayer wrote: and we can even bring back a modified version auto-descend in that case: query(A).filter_by(C, lala=5) since above its not ambiguous. actually, scratch that. C can be related to multiple times. also its ambigious if you want autojoin to kick in or to use joins that are already within the from clause. so i modify my proposal to just whack auto-join period. filter_by(class, **kwargs) will strictly create criterion against class's table using the **kwargs. to make the joins you use join(). no joinpoint is set up. --~--~-~--~~~---~--~~ 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: Weakly-referenced object error
On Jun 1, 2007, at 2:23 PM, Mike Orr wrote: Why can't SQLAlchemy catch this and the gone-away error, refresh the connection, and redo the query like SQLObject does? That's really what one wants, not a pool_recycle time. I think you said that's incompatible with transactions but I don't see how. it does, except for the redo the query part, which would be nightmarish particularly if the previous connection was in a transaction. the entire connection pool is disposed when a dropped connection is detected since it corresponds to the whole DB being shut down. its also a spotty feature since DBAPIs tend to not be very consistent about telling you the connection has gone away. but in your case, the feature seems to not be working on mysql, where i thought it was generally OK. pool_recycle is a more standard way to deal with an expected connection timeout, its totally simple and bypasses the need to ever have to catch any kind of connection closed errors, so I dont think your current errors are due to connections being closed, unless something else is going on. --~--~-~--~~~---~--~~ 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
OK, irc continues, now i see what youre getting at, its this: query.filter_by(['a', 'b', 'c'], foo=bar) query.filter_by('c', foo=bar) i didnt pick up on the list part from the example. that feature specifically starts to look like a django join. the 'join list' at the front is contained within the scope of the filter_by. this implies that the joins should be constructed from aliases so that similar filter_by() calls can be used repeatedly, and also that they wont conflict with any existing joins. --~--~-~--~~~---~--~~ 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
I used to have: .set(**kw) .update(whereclause, **kw) # this does table.update().execute() .count(whereclause) # table.count(whereclause).scalar() .delete_one(id) .load(*args) # returns a mapper with a bunch of eager loads .add_properties(dict) Luckily, great minds think alike and I was able to ditch count and add_properties when I upgraded from 0.1.7 to the 0.3 series. The .load() method is very handy and I think other people might find it useful: @classmethod def load(cls, *args): loads = [eagerload(prop) for prop in args] return cls.options(*loads) It fits my usage patterns well, at least (which is to define everything as lazy-load relations and use .load() to eager load them when it makes sense). shoe On 6/1/07, Christoph Haas [EMAIL PROTECTED] wrote: On Fri, Jun 01, 2007 at 10:50:33AM -0700, David Shoemaker wrote: Both session.query(User).select() and User.query().select() seem more verbose than they need to be for my taste. However, I think most people (myself included) define a base class for all their mapped classes. Uhm, that (few) people I know just use assign_mapper as demonstrated in the many tutorials. Even myself. And now that you mention it I like the idea. Not duplicating what SA is providing but rather making your own life easier. I've always used this base class to provide the interface I want, no matter what interface sqlalchemy provides Now I'm curious. Could you share your base class? That said, if I was new to sqlalchemy, I think I'd be scared to see session.query(User).select() as the recommended way in the tutorial. From lurking on IRC I'm sure most people are indeed scared by SA. :) Christoph -- --- I'd give my right arm to be ambidextrous. --- --~--~-~--~~~---~--~~ 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] should append_whereclause() return the resulting select?
The right usage of append_whereclause() seems to be: s = sometable.select() s.append_whereclause(col==val) etc. I just had a kind of tough time recently when I actually assigned the result instead: s = sometable.select() s = s.append_whereclause(col==val) Granted, this was a mistake I should not have made, and I'm responsible for it. But the resulting behavior was unexpected: s goes to None because append_whereclause() returns None. What I'd rather see is either an error warning not to assign the result to anything, or to just have foo.append_whereclause() return the resulting foo. Is that a reasonable request, or are there reasons it shouldn't be done? Unnecessary, perhaps? Before answering, consider why I feel I made the mistake in the first place. When working with a class instead of a table, the similar process goes thus: q = someclass.query() q = q.filter(col==val) -- so it would be natural/smooth to guess that when I switch a part of my code from dealing with classes to dealing with their mapped tables, I could use similar semantics rather than switching from assignment/ function-evaluation to imperative. No? --~--~-~--~~~---~--~~ 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: should append_whereclause() return the resulting select?
On Jun 1, 2007, at 3:04 PM, Eric Ongerth wrote: The right usage of append_whereclause() seems to be: s = sometable.select() s.append_whereclause(col==val) etc. I just had a kind of tough time recently when I actually assigned the result instead: s = sometable.select() s = s.append_whereclause(col==val) Granted, this was a mistake I should not have made, and I'm responsible for it. But the resulting behavior was unexpected: s goes to None because append_whereclause() returns None. What I'd rather see is either an error warning not to assign the result to anything, or to just have foo.append_whereclause() return the resulting foo. Is that a reasonable request, or are there reasons it shouldn't be done? Unnecessary, perhaps? Before answering, consider why I feel I made the mistake in the first place. When working with a class instead of a table, the similar process goes thus: q = someclass.query() q = q.filter(col==val) -- so it would be natural/smooth to guess that when I switch a part of my code from dealing with classes to dealing with their mapped tables, I could use similar semantics rather than switching from assignment/ function-evaluation to imperative. No? making select() 'generative' has been under discussion. questions include whether to copy the select each time before returning it as well as what the methods should be called, i.e. maybe where() instead of append_whereclause(). --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Friday 01 June 2007 21:38:15 Michael Bayer wrote: On Jun 1, 2007, at 1:24 PM, Michael Bayer wrote: and we can even bring back a modified version auto-descend in that case: query(A).filter_by(C, lala=5) since above its not ambiguous. actually, scratch that. C can be related to multiple times. also its ambigious if you want autojoin to kick in or to use joins that are already within the from clause. so i modify my proposal to just whack auto-join period. heh, if i remember how whole-heartly u defended this autodescend thing some months ago... IMO u can have some configuration arg like autodescendjoin =False by default (or True to have it compatible with old code/lazy programmers) -- IF u want to somehow keep that unreliable traversal-guess at all. Another herotic idea: look around the overriding userclass' __init__ method and why that is needed. This seems to me to be somehow connected to assignmapper, it's again about autoguessing mappers/sessions. IMO these notions (mapping, session-attaching, etc similar attaching of user-klas/obj to some DB/ORM-related thing) can be separated and have a possibility to make any combination of those, not just one hardcoded. e.g. the same way u can have now assignmapper vs not have one, u should have auto-mapper-compilation vs non-auto. and more IMO, i think all these auto-guessing things in SA (and u have many,many of them, and u like them) are _okay_ as far as there is a way to disable them and require/specify all explicitly. Whether the default would be the (easy) autoguess or not, is irrelevant here. did u get my point? ciao svil --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Jun 1, 2007, at 5:33 PM, [EMAIL PROTECTED] wrote: heh, if i remember how whole-heartly u defended this autodescend thing some months ago... we didnt have generative behavior built into query so there was no way to conveniently get at an attribute based on a join. and more IMO, i think all these auto-guessing things in SA (and u have many,many of them, and u like them) are _okay_ as far as there is a way to disable them and require/specify all explicitly. i cant think of other places in SA that are literally guessing. we have a lot of assuming as well as defaults. these are not guesses because they are deterministic. a guess means you have more than one choice, and you pick one - randomly, or based on other things that were random (like dictionary ordering). it cant be predicted. if you map a relation from class A to B, we assume the join condition is based on the foreign keys between A and B's table. if I say A.join(B), the only possible way to join them unless explicitly stated is along their foreign keys (or I suppose you could say their column names, but that would be silly). thats not a guess...it will do the same thing every time. another example of a default is if you map a relation from A-A, it places the foreign key on the right side of the relation by default unless you specify remote side. thats also not a guess. the topological sort that occurs during a flush - there is a degree of non-determinism there to the extent that more than one ordering exists for a given set of dependencies. but it *is* deterministic that the resulting ordering will be correct. theres no guess there, just that the specific ordering is just undefined, just like for a dictionary. if there were many, many guesses going on, we'd have many, many broken applications. --~--~-~--~~~---~--~~ 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: should append_whereclause() return the resulting select?
On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: What I'd rather see is either an error warning not to assign the result to anything, or to just have foo.append_whereclause() return the resulting foo. Is that a reasonable request, or are there reasons it shouldn't be done? Unnecessary, perhaps? making select() 'generative' has been under discussion. questions include whether to copy the select each time before returning it as well as what the methods should be called, i.e. maybe where() instead of append_whereclause(). Returning None is a Python standard, see list.sort(). Making select generative is OK, but it should either modify the select in place or return a new one, not modify it and return it. That's a Perlism. There should be one-- and preferably only one --obvious way to do it. Something shorter than .append_whereclause() would be nice. .append_where or just .where come to mind. -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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
assign_mapper is doing five different things: 1 Hide the session context and session 2 .query() 3 shadowed query methods (get*/select*/count/join*/etc) 4 shadowed session methods (flush/delete/save/etc) 5 connecting a DynamicMetaData whenever it needs to (1) we all agree is very useful. (2) is more straightforward to the user than session.query(MyClass). (3) is under probation. (4) I haven't used so I'm not sure if it's better or worse than session.* . But grafting fewer rather than more methods onto the mapped class makes sense. (5) is maybe being done by the session_context rather than assign_mapper, so perhaps it doesn't apply here. I just saw a Pylons recipe that said you can use a DynamicMetaData in your model *if* you use assign_mapper; I'm not sure why. http://docs.pythonweb.org/display/pylonscookbook/SQLAlchemy+for+people+in+a+hurry Given that all this is in control of the session_context, why not make assign_mapper a method of it, with boolean flags to enable method decoration: session_context.map(MyClass, table, query_methods=True, session_methods=True) or: session_context.query_methods = True session_context.session_methods = True session_context.map(MyClass, table) If we hang the query methods off .query(), can we hang the session methods off .session()? Or .store. (But not .objectstore, ugh.) Michael Bayer wrote: as it turns out, assign_mapper's monkeypatched methods (and they are all monkeypatched, not sure why you singled out query()) .query() is a class method that's actually a lambda. Very strange. The other methods looked like they were assigned more straightforwardly but maybe that's just a superficial appearance. They don't use lambdas though. -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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: should append_whereclause() return the resulting select?
On Jun 1, 2007, at 5:58 PM, Mike Orr wrote: Returning None is a Python standard, see list.sort(). Making select generative is OK, but it should either modify the select in place or return a new one, not modify it and return it. That's a Perlism. There should be one-- and preferably only one --obvious way to do it. i am glad to see someone take a position on this. but the modify in place and return it thing is also how Hibernate criteria queries work. one advantage to modify in place (and not return it, or whatever) is one of performancean app thats constantly generating a particular select in a generative fashion spends a lot of time creating and copying multiple select instances..and i think the overhead to creating a select() is higher than a mapper query since the select has more complicated state. thats the main reason im hesitant to make copying behavior in select() so prevalent. --~--~-~--~~~---~--~~ 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: should append_whereclause() return the resulting select?
On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: the modify in place and return it thing is also how Hibernate criteria queries work. I know nothing about Hibernate. Why is it so great and why are we imitating it? According to Wikipedia it's a Java db framework. So we should make sure we're not borrowing Javaisms in the API without a compelling reason. -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: assign_mapper query methods
On Jun 1, 2007, at 6:47 PM, Mike Orr wrote: (4) I haven't used so I'm not sure if it's better or worse than session.* . But grafting fewer rather than more methods onto the mapped class makes sense. instance.flush() is often misused, since flush() with just one instance wont always flush dependent instances. session.flush() is preferred, so ive considered whacking this since i think instance.flush() is not as common a use case as people might think (and they can say session.flush([instance]) if they really want the single-instance flush). 5 connecting a DynamicMetaData whenever it needs to (5) is maybe being done by the session_context rather than assign_mapper, so perhaps it doesn't apply here. I just saw a Pylons recipe that said you can use a DynamicMetaData in your model *if* you use assign_mapper; I'm not sure why. http://docs.pythonweb.org/display/pylonscookbook/SQLAlchemy+for +people+in+a+hurry we assignmapper has nothing to do with metadata or engines at all. also i kind of want to log in and edit that. DynamicMetaData, it was recently agreed, is not of general use. it connects to a particular engine within the current thread only. Pylons generally does not require any engine to be bound to the metadata at all since it binds the engine to the session. Given that all this is in control of the session_context, why not make assign_mapper a method of it, with boolean flags to enable method decoration: session_context.map(MyClass, table, query_methods=True, session_methods=True) or: session_context.query_methods = True session_context.session_methods = True session_context.map(MyClass, table) i think assignmapper is a much more second class citizen than session_context. people are at last talking about making their own common base class with actual methods on them, instead of using any of this monkeypatch stuff. If we hang the query methods off .query(), can we hang the session methods off .session()? Or .store. (But not .objectstore, ugh.) .session maybe. .query() is a class method that's actually a lambda. Very strange. The other methods looked like they were assigned more straightforwardly but maybe that's just a superficial appearance. They don't use lambdas though. i use lambdas for short anonymous functions all the time ? oh well i guess im under arrest by the style police again. (repeat offender...) --~--~-~--~~~---~--~~ 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
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). --~--~-~--~~~---~--~~ 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: Weakly-referenced object error
No weak-reference error this morning, hooray. I'll be watching it for a few days. Could using a BoundMetaData in my model be contributing to the problem? I have the following structure: === ctx = get_session_context() # A custom function that creates a session_context like # pylons.database, but reads more engine options from the # config file. engine = ctx.current.bind_to meta = BoundMetaData(engine) incidents = Table(..., meta, autoload=True) ic = incident.columns class Incident(object): pass assign_mapper(ctx, Incident, incidents) def list_incidents(top_only): q = Incident.query() if top_only: q = q.filter(Incident.c.is_top) return q === So when list_incidents() is called it's in a different thread than where all the variables were defined. The engine and metadata are thread safe, right? Should I use a DynamicMetaData and temporarily connect it to define the tables, and then connect it to None? Or would that just me making things more complicated for no reason? As far as I can tell there's only one engine shared throughout the application anyway, so it shouldn't harm anything to use a BoundMetaData. Could we have session.engine be an alias for session.bind_to? Pretty please? The only reason I leave a top-level 'engine' around is in case I need it for something, because .bind_to is so non-obvious. -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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: should append_whereclause() return the resulting select?
On Jun 1, 2007, at 7:07 PM, Mike Orr wrote: On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: the modify in place and return it thing is also how Hibernate criteria queries work. I know nothing about Hibernate. Why is it so great and why are we imitating it? According to Wikipedia it's a Java db framework. So we should make sure we're not borrowing Javaisms in the API without a compelling reason. just sayin, its not perl :) --~--~-~--~~~---~--~~ 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: Weakly-referenced object error
On Jun 1, 2007, at 7:22 PM, Mike Orr wrote: No weak-reference error this morning, hooray. I'll be watching it for a few days. Could using a BoundMetaData in my model be contributing to the problem? I have the following structure: i cant see how. all of that code internally uses connections from the connection pool for just one operation , then sends it right back to the pool with an explicit close(). we arent hanging on to any MySQLDB resources in any unusual way. So when list_incidents() is called it's in a different thread than where all the variables were defined. The engine and metadata are thread safe, right? yes, they have no mutable state for the most part (unless you say engine.dispose() or metadata.connect()). Should I use a DynamicMetaData and temporarily connect it to define the tables, and then connect it to None? Or would that just me making things more complicated for no reason? dont use DMD. not for any reason other than its needlessly complicated, yes. As far as I can tell there's only one engine shared throughout the application anyway, so it shouldn't harm anything to use a BoundMetaData. thats right. Could we have session.engine be an alias for session.bind_to? Pretty please? The only reason I leave a top-level 'engine' around is in case I need it for something, because .bind_to is so non-obvious. pylons is the reason pulling the engine off the session is even becoming popular, because it is actually using the bind_to feature, as well as that it didnt really create any easy way to get at the engine repository (not to mention the issues i raised on the pylons list). things to note about bind_to is that the session may not be bound to anything, and also can be bound to *multiple* engines in the case that someone is making it do that. which is why the official way to get the engine is session.get_bind(mapper). i dont know what im saying here other than im getting a little antsy about session / engine /etc being muddied / TMTOWTDI. theres too many choices but in this case people wanted them. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Weakly-referenced object error
On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: Mike Orr wrote: Could we have session.engine be an alias for session.bind_to? Pretty please? The only reason I leave a top-level 'engine' around is in case I need it for something, because .bind_to is so non-obvious. pylons is the reason pulling the engine off the session is even becoming popular, because it is actually using the bind_to feature, as well as that it didnt really create any easy way to get at the engine repository (not to mention the issues i raised on the pylons list). things to note about bind_to is that the session may not be bound to anything, and also can be bound to *multiple* engines in the case that someone is making it do that. which is why the official way to get the engine is session.get_bind(mapper). i dont know what im saying here other than im getting a little antsy about session / engine /etc being muddied / TMTOWTDI. theres too many choices but in this case people wanted them. I assume you're referring to this thread: http://groups.google.com/group/pylons-discuss/browse_thread/thread/747ac14d1e20f332/a650fb1011ec2387?lnk=gstq=michael+bayer+sqlalchemyrnum=1 Subject: Pylons Integration of SQLAlchemy config extremely broken Date: 2007-05-25 A couple older threads which are slightly obsolete: http://groups.google.com/group/pylons-discuss/browse_thread/thread/70fecb3d8da1aec8/a78e2fb66d8e4baa?lnk=gstq=michael+bayer+sqlalchemyrnum=5 Subject: SQLAlchemy best practices Date: 2006-09-20 http://groups.google.com/group/pylons-discuss/browse_thread/thread/1f05fee97b1e5217/f424e9f51f7e3627?lnk=gstq=michael+bayer+sqlalchemyrnum=6#f424e9f51f7e3627 Subject: ANN: Pylons 0.9.4 released Date: 2006-12-30 There is agreement in the Pylons group that pylons.database needs to be improved. Both you and I and others need to pass in more create_engine options. I'm contemplating a patch that would read all currently-defined options from the config file, converting those known to be ints or bool, and skipping those requiring non-scalar values. That would solve a large chunk of people's problems. Multiple engines make my head spin. Why do you need that unless you're connecting to two different databases in the same application? And even if you did, wouldn't you define a second top-level session_context to bind it to, with its own different metadata and tables, and never the twain shall mix? I don't want a registry of engines or something in the 'g' object. What I want is a simple out-of-the box configuration for simple sites, but more robust than what Pylons currently has. Maybe we'll have to come up with separate simple and advanced configurations if others need multiple engines and whatnot. I also don't like how pylons.database initializes a session_context at import time rather than providing a create_session_context function, so that's another thing to add to my patch. Otherwise if you can't use pylons.database.create_engine() for some reason, you have to duplicate a lot of code to recreate or bypass the default session_context, and this includes writing stub functions because SessionContext takes a session factory function with takes a create_engine function, so there's no way to customize the create_engine from the SessionContext constructor directly. Methinks SQLAlchemy is contributing to the problem with its long hierarchy of engine - metadata - session - session_context, but I don't have the expertise to say what might be better. But certainly it's annoying that: - SessionContext doesn't take both create_engine and make_session arguments, or arguments to pass through to those, and build your ideal engine - session - session_context hierarchy on the fly. Instead you have to create a dummy make_session function just to tell it which create_engine to use. This is part of why overriding Pylons' default session_context requires reimplementing three whole functions. - This is a part of the previous, but SessionContext in the manual says, A common customization is a Session which needs to explicitly bind to a particular Engine. Yes, so why doesn't SQLAlchemy provide a way to handle this common case without the user having to define his own make_session? Again, SessionContext -- or a create_session_context function -- could do this for you if you pass an 'engine' argument. - Metadata seems like an implementation detail. I have to define a metadata just to pass it to my Table's, then I never use it again. There is global_connect() which hides it, but its use seems discouraged. Plus global_connect gets into all that DynamicMetaData complication, such as whether it will autoconnect properly in the other threads. Perhaps what I'm asking for is a global_bound_connect or something? I can see why the metadata can't be subsumed into the engine because you may want to connect the same metadata back and forth if you're copying data from one database to another. And I can see why it can't be subsumed into
[sqlalchemy] Re: Weakly-referenced object error
On 6/1/07, Michael Bayer [EMAIL PROTECTED] wrote: pylons is the reason pulling the engine off the session is even becoming popular, because it is actually using the bind_to feature, as well as that it didnt really create any easy way to get at the engine repository (not to mention the issues i raised on the pylons list). things to note about bind_to is that the session may not be bound to anything, and also can be bound to *multiple* engines in the case that someone is making it do that. which is why the official way to get the engine is session.get_bind(mapper). Well, I guess it's a Pylonsism but the session is always bound to an engine at this point, and no mappers exist yet. I'm not sure how your one engine registry or engine key would help with this. You're saying people should just get the engine through pylons.database.engines[default] or something rather than going through the session_context? Alternatively, pylons.database could expose the global engine. Or one could have a SQLAlchemy class with .create_engine(), .make_session(), .create_session_context() methods. Then it would be easy to subclass that if you need to override one of the parts, and the other parts would automatically use your new method. Then the default model would have: from pylons database import SQLAlchemy sqla = SQLAlchemy() engine = sqla.create_engine() ctx = sqla.session_context() Does that sound like a good approach? Could it be made to scale for multiple engines by adding some engine key arguments? Also, the create_engine method could hand back a cached engine if a compatible one has already been created. -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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] Bug in .query()[11:22]
I'm transforming a query from .select(offset=start, limit=rpp) to .query()[:] syntax. ('rpp' means records per page.) Stupidly I transformed it directly into: .query()[start:rpp] which in one transaction evaluates to: .query()[1420:20] This causes a SQL syntax error with the actual query containing: ... LIMIT -1400 OFFSET 1420 Apparently a negative limit is illegal in MySQL. Of course I should have done it this way: .query()[start:start+rpp] because the second number is supposed to be one past the last index, not the number of records to return. This results in a much more reasonable: .query()[1420:1440] ... LIMIT 20 OFFSET 1420 My point is, if the second number is lower than the first, shouldn't SQLAlchemy transform it into a query that returns no records? I.e., LIMIT 0, which MySQL at least allows. Because that's what the Python equivalent would do: range()[1420:20] [] -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---