[sqlalchemy] Re: UOW relation delete bug
it works for me, the bind params are in sqlite: [[1], [3], [5]] in postgres: [{'id': 1}, {'id': 3}, {'id': 5}] in both cases, thats a list of three sets of bind params, one positional and the other named, which correspond to executemany(). if this condition doesnt work with MS-SQL, MS-SQL should get added to test/engine/execute.py, which test the various scenarios of *multiparams and **params that you can send to execute(). just pick the paramstyle that works with MS-SQL and add it to the supported list for that test. On Mar 28, 2007, at 1:36 AM, Rick Morrison wrote: Surprised no one has hit this one yet. When issuing a series of deletes in a UOW, SA issues the bogus delete statement DELETE child where id = [1,2,3] instead of using IN() Test case attached. Seems to work in Sqlite even while issuing the bogus SQL (which is probably why a unit test didn't pick it up), but MS-SQL doesn't like it; didn't check PG or others. from sqlalchemy import * import logging logging.basicConfig() logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO) #metadata = BoundMetaData('mssql://d:[EMAIL PROTECTED]/drvtest') metadata = BoundMetaData('sqlite:///:memory:') entity = Table('entity', metadata, Column('id', INT, primary_key=True, nullable=False), Column('typ', VARCHAR(12)), Column('lname', VARCHAR(128)) ) entityattr = Table('entityattr', metadata, Column('id', INT, primary_key=True, nullable=False), Column('ident', INT, ForeignKey('entity.id'), nullable=False), Column('typ', VARCHAR(12), nullable=False), Column('val', VARCHAR(128)) ) metadata.create_all() class O(object): def __init__(self,**kw): for k,v in kw.items(): setattr(self,k,v) class Ent(O): pass class Entattr(O): pass mapper(Ent, entity, properties = {'props':relation(Entattr, cascade=all, delete-orphan)}) mapper(Entattr, entityattr) S = create_session() S.save(Ent(typ='A',lname='A', props = [Entattr(typ='A1', val='1'), Entattr(typ='A2', val='2'), Entattr(typ='A3', val='3'), Entattr(typ='A4', val='4'), Entattr(typ='A5', val='5'), Entattr(typ='A6', val='6') ])) S.flush() S.clear() e = S.query(Ent).options(eagerload('props')).select()[0] # remove some attributes e.props = [p for p in e.props if 0 == int(p.val) % 2] # put some back e.props.append(Entattr(typ='A6', val='6')) e.props.append(Entattr(typ='A7', val='7')) e.props.append(Entattr(typ='A8', val='8')) S.flush()# -- Delete issued here S.clear() e = S.query(Ent).options(eagerload('props')).select()[0] assert 6 == len(e.props) metadata.drop_all() --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Fix on ADODBAPI
Hi, The bit applicable to adodbapi doesn't consider the port at all (at the moment...) class MSSQLDialect_adodbapi(MSSQLDialect): ... def make_connect_string(self, keys): connectors = [Provider=SQLOLEDB] connectors.append (Data Source=%s % keys.get(host)) connectors.append (Initial Catalog=%s % keys.get(database)) user = keys.get(user) if user: connectors.append(User Id=%s % user) connectors.append(Password=%s % keys.get(password, )) else: connectors.append(Integrated Security=SSPI) return [[;.join (connectors)], {}] Paul El Gringo wrote: Ok I saw fixes in the current trunk: class MSSQLDialect_pymssql(MSSQLDialect): def make_connect_string(self, keys): if keys.get('port'): # pymssql expects port as host:port, not a separate arg keys['host'] = ''.join([keys.get('host', ''), ':', str(keys['port'])]) del keys['port'] return [[], keys] I guess the right separator is not ':' but ','. G just a way from MS to disagree from standarts. --~--~-~--~~~---~--~~ You 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: Fix on ADODBAPI
On 28 mar, 12:30, Paul Johnston [EMAIL PROTECTED] wrote: Hi, The bit applicable toadodbapidoesn't consider the port at all (at the moment...) Check the current trunk, if port is specified, the port key is deleted and its value added to the key host with ''.join([keys.get('host', ''), ':', str(keys['port'])]) . The problem is the ':' wich must be a coma for an adodb connection string. check http://msdn2.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring.aspx. server=tcp:servername, portnumber --~--~-~--~~~---~--~~ You 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: func() bug ?
Hello Mike, This simple test illustrate the problem : from sqlalchemy import func print 'foo' == func.any('bar') any(:any) = :a_1 it should be :a_1 = any(:any) If you look at the PostgreSQL documentation, http://www.postgresql.org/docs/8.2/static/functions-comparisons.html#AEN14105 the syntax is: expression operator ANY (array expression) and not : ANY (array expression) expression operator Note the ANY can also be used with subselect (so it's not specific to the PostgreSQL array type) : http://www.postgresql.org/docs/8.2/static/functions-subquery.html#AEN13959 expression operator ANY (subquery) and in this case it's also incorrect : print 'foo' == func.any(select) any(:any) = :a_1 (again it should be :a_1 = any(:any)) Regards, Julien On Tue, 2007-03-27 at 12:13 -0400, Michael Bayer wrote: also we dont really have any direct support for python array types, which seemed to be an element of your test. can you try a basic func test without an array type being used ? On Mar 27, 2007, at 10:58 AM, Julien Cigar wrote: The query is rather complicated: http://rafb.net/p/qyx3vA47.html The problem is at line 95 (the FIXME) Thanks Michael Bayer wrote: On Mar 27, 2007, at 10:00 AM, Julien Cigar wrote: Hello, I'm using SQLAlchemy 0.3.5, and it seems that the func() output is broken with some functions. I use the ANY function of PostgreSQL with something like : func.any(q.c.habitats)==filter_habitat SQLAlchemy translates this in: WHERE any(habitats) = %(any)s, which is incorrect. For example: the result should be : iasdev= select true as result where 'abc' = ANY(array['abc', 'def']); result t where SQLAlchemy generates the query as : iasdev= select true as result where ANY(array['abc', 'def']) = 'abc'; ERROR: syntax error at or near ANY at character 29 LINE 1: select true as result where ANY(array['abc', 'def']) = 'abc'... Is this a bug ? (or maybe it's possible to keep the order...) ? can i have some complete code examples please ? i dont understand how your snippet would produce a full SELECT statement. the phrase youve shown me translates exactly as specified, assuming filter_habitat is ia non ClauseElement:: func.any(q.c.habitats)==filter_habitat should be: any(habitats) = %(any)s -- Julien Cigar Belgian Biodiversity Platform http://www.biodiversity.be Universit� Libre de Bruxelles (ULB) Campus de la Plaine CP 257 B�timent NO, Bureau 4 N4 115C (Niveau 4) Boulevard du Triomphe, entr�e ULB 2 B-1050 Bruxelles office: [EMAIL PROTECTED] home: [EMAIL PROTECTED] biobel reference: http://biobel.biodiversity.be/biobel/person/show/471 -- Julien Cigar Belgian Biodiversity Platform http://www.biodiversity.be Universit� Libre de Bruxelles Campus de la Plaine CP 257 B�timent NO, Bureau 4 N4 115C (Niveau 4) Boulevard du Triomphe, entr�e ULB 2 B-1050 Bruxelles mail: [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: func() bug ?
a few things here. first of all, if its an operator, you probably want to use op(): literal('foo').op('ANY')('bar') secondly, when you say x == ClauseElement, the __eq__() method in Python that gets called on the clauseelement has no reversed version. so its impossible for the ClauseElement on the right to know that it should be on the left. you can work around this similarly to the previous example, by making both sides a ClauseElement and saying: literal('foo') == func.any('bar') On Mar 28, 2007, at 10:42 AM, Julien Cigar wrote: Hello Mike, This simple test illustrate the problem : from sqlalchemy import func print 'foo' == func.any('bar') any(:any) = :a_1 it should be :a_1 = any(:any) If you look at the PostgreSQL documentation, http://www.postgresql.org/docs/8.2/static/functions- comparisons.html#AEN14105 the syntax is: expression operator ANY (array expression) and not : ANY (array expression) expression operator Note the ANY can also be used with subselect (so it's not specific to the PostgreSQL array type) : http://www.postgresql.org/docs/8.2/static/functions- subquery.html#AEN13959 expression operator ANY (subquery) and in this case it's also incorrect : print 'foo' == func.any(select) any(:any) = :a_1 (again it should be :a_1 = any(:any)) Regards, Julien On Tue, 2007-03-27 at 12:13 -0400, Michael Bayer wrote: also we dont really have any direct support for python array types, which seemed to be an element of your test. can you try a basic func test without an array type being used ? On Mar 27, 2007, at 10:58 AM, Julien Cigar wrote: The query is rather complicated: http://rafb.net/p/qyx3vA47.html The problem is at line 95 (the FIXME) Thanks Michael Bayer wrote: On Mar 27, 2007, at 10:00 AM, Julien Cigar wrote: Hello, I'm using SQLAlchemy 0.3.5, and it seems that the func() output is broken with some functions. I use the ANY function of PostgreSQL with something like : func.any(q.c.habitats)==filter_habitat SQLAlchemy translates this in: WHERE any(habitats) = %(any)s, which is incorrect. For example: the result should be : iasdev= select true as result where 'abc' = ANY(array['abc', 'def']); result t where SQLAlchemy generates the query as : iasdev= select true as result where ANY(array['abc', 'def']) = 'abc'; ERROR: syntax error at or near ANY at character 29 LINE 1: select true as result where ANY(array['abc', 'def']) = 'abc'... Is this a bug ? (or maybe it's possible to keep the order...) ? can i have some complete code examples please ? i dont understand how your snippet would produce a full SELECT statement. the phrase youve shown me translates exactly as specified, assuming filter_habitat is ia non ClauseElement:: func.any(q.c.habitats)==filter_habitat should be: any(habitats) = %(any)s -- Julien Cigar Belgian Biodiversity Platform http://www.biodiversity.be Universit� Libre de Bruxelles (ULB) Campus de la Plaine CP 257 B�timent NO, Bureau 4 N4 115C (Niveau 4) Boulevard du Triomphe, entr�e ULB 2 B-1050 Bruxelles office: [EMAIL PROTECTED] home: [EMAIL PROTECTED] biobel reference: http://biobel.biodiversity.be/biobel/person/ show/471 -- Julien Cigar Belgian Biodiversity Platform http://www.biodiversity.be Universit� Libre de Bruxelles Campus de la Plaine CP 257 B�timent NO, Bureau 4 N4 115C (Niveau 4) Boulevard du Triomphe, entr�e ULB 2 B-1050 Bruxelles mail: [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] Using entry points to load database dialects
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
[sqlalchemy] Re: mssql using pymssql 0.8 and sqlalchemy 0.3.6
the table I'm trying to grab is under 30 chars. Is there a way to change this limit? On Mar 28, 12:23 pm, Rick Morrison [EMAIL PROTECTED] wrote: Pymssql uses DBlib under the covers, and there's a 30-character identifier limit in DBlib. That limit applies to any identifier, including table and column names, which might explain your second issue. Rick On 3/28/07, Lee Connell [EMAIL PROTECTED] wrote: I am using these tools on a windows machine. Some problems I ran into. First of all I can't connect to a database that's name is more than 30 chars long. Error returned says it can't find the database and the database it's looking for has been truncated. When I connect to a database less than 30 chars long, I try to load a table and it complains that it cannot find the table. The table is definitely there and I've tried many different table names as well that are available in the DB. Anyone know of a fix or is this a bug? ### Here is my code. # from sqlalchemy import * db_name = this_is_a_test_of_a_long_database_string db_user = lee db_pass = db_conn = mssql://%s:[EMAIL PROTECTED]/%s % (db_user, db_pass, db_name) db = create_engine(db_conn, echo=True) metadata = BoundMetaData(db) users_table = Table(syscolumns, metadata, autoload=True) list(users_table.columns)[0].name # Ammonoosuc_Computer_Services_MSCRM # FilteredServiceAppointment --~--~-~--~~~---~--~~ You 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: mssql using pymssql 0.8 and sqlalchemy 0.3.6
There is a fix for column names, however I don't see anything to overcome this issue if the database name is more than 30 chars? Any suggestions? On Mar 28, 12:44 pm, Lee Connell [EMAIL PROTECTED] wrote: the table I'm trying to grab is under 30 chars. Is there a way to change this limit? On Mar 28, 12:23 pm, Rick Morrison [EMAIL PROTECTED] wrote: Pymssql uses DBlib under the covers, and there's a 30-character identifier limit in DBlib. That limit applies to any identifier, including table and column names, which might explain your second issue. Rick On 3/28/07, Lee Connell [EMAIL PROTECTED] wrote: I am using these tools on a windows machine. Some problems I ran into. First of all I can't connect to a database that's name is more than 30 chars long. Error returned says it can't find the database and the database it's looking for has been truncated. When I connect to a database less than 30 chars long, I try to load a table and it complains that it cannot find the table. The table is definitely there and I've tried many different table names as well that are available in the DB. Anyone know of a fix or is this a bug? ### Here is my code. # from sqlalchemy import * db_name = this_is_a_test_of_a_long_database_string db_user = lee db_pass = db_conn = mssql://%s:[EMAIL PROTECTED]/%s % (db_user, db_pass, db_name) db = create_engine(db_conn, echo=True) metadata = BoundMetaData(db) users_table = Table(syscolumns, metadata, autoload=True) list(users_table.columns)[0].name # Ammonoosuc_Computer_Services_MSCRM # FilteredServiceAppointment --~--~-~--~~~---~--~~ You 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: Confused by foreign_keys argument
That compiles and appears to run in the small test program attached, but if you look at the query generated when accessing the 'cs' property, it doesn't actually use the join condition: SELECT c.id AS c_id, c.name AS c_name FROM c, a_b, b_c WHERE ? = a_b.a_id AND b_c.c_id = c.id ORDER BY a_b.oid ie. the a_b.b_id = b_c.b_id clause is missing. If you aren't keen on the 'viewonly' pattern, how would you recommend doing this? Just by adding a normal python property and doing a query? The main reason I like setting it up as a relation is for the potential of making it eager-loading just by changing a single flag. Thanks, Simon From: sqlalchemy@googlegroups.com [mailto:[EMAIL PROTECTED] On Behalf Of Michael Bayer Sent: 28 March 2007 17:19 To: sqlalchemy@googlegroups.com Subject: [sqlalchemy] Re: Confused by foreign_keys argument what it cant locate are foreign keys between the parent and child tables, a and cbecause there arent any. when you have a many-to-many, the rules for figuring out the relationship change, and it knows to do that by the presence of the secondary argument. so if you can manufacture a secondary table you can do this: secondary = a_b_table.join(b_c_table, onclause=a_b_table.c.b_id==b_c_table.c.b_id) mapper( A, a_table, properties={'cs': relation(C, secondary=secondary, primaryjoin=a_table.c.id==secondary.c.a_b_a_id, secondaryjoin=secondary.c.b_c_c_id==c_table.c.id, viewonly=True, ) } ) im not totally sure the lazy clause is going to work but try it out. this goes back to my general dislike of viewonly and how i cant generally support it, becuase as the rules for relationships get more strict and accurate, cases like these become harder to model. On Mar 28, 2007, at 10:39 AM, King Simon-NFHD78 wrote: a_table = Table('a', metadata, Column('id', Integer, primary_key=True), Column('name', String(16)), ) b_table = Table('b', metadata, Column('id', Integer, primary_key=True), Column('name', String(16)), ) c_table = Table('c', metadata, Column('id', Integer, primary_key=True), Column('name', String(16)), ) a_b_table = Table('a_b', metadata, Column('a_id', Integer, ForeignKey('a.id'), primary_key=True), Column('b_id', Integer, ForeignKey('b.id'), primary_key=True), ) b_c_table = Table('b_c', metadata, Column('b_id', Integer, ForeignKey('b.id'), primary_key=True), Column('c_id', Integer, ForeignKey('c.id'), primary_key=True) ) class A(object): pass class B(object): pass class C(object): pass mapper(B, b_table) mapper(C, c_table) # # How can I create a mapper on A with a property that gives # all the 'C' objects? # # This doesn't work - it requires the foreign_keys parameter # to be passed, but I don't know what to pass. mapper( A, a_table, properties={'cs': relation(primaryjoin=and_(a_table.c.id == a_b_table.c.a_id, a_b_table.c.b_id == b_c_table.c.b_id, c_table.c.id == b_c_table.c.c_id), viewonly=True, ) } ) --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~--- join2.py Description: join2.py
[sqlalchemy] Re: UOW relation delete bug
On Mar 28, 1:15 pm, Rick Morrison [EMAIL PROTECTED] wrote: Hey Mike, this looks to be related to the parameters-as-ClauseParameters instead of Python dict() on a different thread. you mean the thing i just checked in yesterday ? OK yeah, youve always been getting a ClauseParameters object, its just it subclassed dict. I removed that becuase the API of ClauseParameters was getting totally muddy and i didnt even understand how it worked anymore. so now its more explicit fields with their behaviors more clearly separated. but it still has a __getitem__ and a __contains__ on it and we can put keys() there as well, so what more dictlike behavior do you need ? I'm going to need some help or advice beating the MSSQL module into shape with the new convention. Where does the positional / non-positional specification go? I don't see it in any of the DB modules. we are usually calling paramstyle off the DBAPI itself to figure that out. that might have to change soon when I address the ImportError ticket. --~--~-~--~~~---~--~~ You 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: UOW relation delete bug
Hey Mike, this looks to be related to the parameters-as-ClauseParameters instead of Python dict() on a different thread. I'm going to need some help or advice beating the MSSQL module into shape with the new convention. Where does the positional / non-positional specification go? I don't see it in any of the DB modules. Looks like pymssql wants positional -style parameters, anyone know about adbodbapi / pyodbc?. Rick On 3/28/07, Michael Bayer [EMAIL PROTECTED] wrote: it works for me, the bind params are in sqlite: [[1], [3], [5]] in postgres: [{'id': 1}, {'id': 3}, {'id': 5}] in both cases, thats a list of three sets of bind params, one positional and the other named, which correspond to executemany(). if this condition doesnt work with MS-SQL, MS-SQL should get added to test/engine/execute.py, which test the various scenarios of *multiparams and **params that you can send to execute(). just pick the paramstyle that works with MS-SQL and add it to the supported list for that test. On Mar 28, 2007, at 1:36 AM, Rick Morrison wrote: Surprised no one has hit this one yet. When issuing a series of deletes in a UOW, SA issues the bogus delete statement DELETE child where id = [1,2,3] instead of using IN() Test case attached. Seems to work in Sqlite even while issuing the bogus SQL (which is probably why a unit test didn't pick it up), but MS-SQL doesn't like it; didn't check PG or others. from sqlalchemy import * import logging logging.basicConfig() logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO) #metadata = BoundMetaData('mssql://d:[EMAIL PROTECTED]/drvtest') metadata = BoundMetaData('sqlite:///:memory:') entity = Table('entity', metadata, Column('id', INT, primary_key=True, nullable=False), Column('typ', VARCHAR(12)), Column('lname', VARCHAR(128)) ) entityattr = Table('entityattr', metadata, Column('id', INT, primary_key=True, nullable=False), Column('ident', INT, ForeignKey('entity.id'), nullable=False), Column('typ', VARCHAR(12), nullable=False), Column('val', VARCHAR(128)) ) metadata.create_all() class O(object): def __init__(self,**kw): for k,v in kw.items(): setattr(self,k,v) class Ent(O): pass class Entattr(O): pass mapper(Ent, entity, properties = {'props':relation(Entattr, cascade=all, delete-orphan)}) mapper(Entattr, entityattr) S = create_session() S.save(Ent(typ='A',lname='A', props = [Entattr(typ='A1', val='1'), Entattr(typ='A2', val='2'), Entattr(typ='A3', val='3'), Entattr(typ='A4', val='4'), Entattr(typ='A5', val='5'), Entattr(typ='A6', val='6') ])) S.flush() S.clear() e = S.query(Ent).options(eagerload('props')).select()[0] # remove some attributes e.props = [p for p in e.props if 0 == int(p.val) % 2] # put some back e.props.append(Entattr(typ='A6', val='6')) e.props.append(Entattr(typ='A7', val='7')) e.props.append(Entattr(typ='A8', val='8')) S.flush()# -- Delete issued here S.clear() e = S.query(Ent).options(eagerload('props')).select()[0] assert 6 == len(e.props) metadata.drop_all() --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: sqlalchemy orm doesn't create an instance of certain rows
the issue is that the built-in relationship joining facilities dont know how to generate joins for self-referential relationships that you could then reference externally in your criterion. while its easy enough for the join to add in an alias there, all subsequent operations on the query would need some way of identifying a criterion as applied to the original table or the aliased table. so its an API issue. I just added an error message that will be raised as of r2456. so the explicit way to do it is this: nodealias = nodeTable.alias('nodealias') query.select_from(nodeTable.join(nodealias, onclause=nodealias.c.node_id==nodeTable.c.console_id)).select (nodealias.c.name=='console1..com') we can perhaps add some helpers to join() such as : query.join('consoleNodes', using=nodealias) so that at least the onclause construction wouldnt be needed. but we'd have to define things like this mean: query.join(['a', 'b, 'c', 'd'], using=[alias1, alias2, alias3]) On Mar 28, 2007, at 12:42 PM, Karthik Krishnamurthy wrote: #!/usr/bin/env python from sqlalchemy import * metadata = BoundMetaData('sqlite:///', name='opsdb') metadata.engine.echo = True session = create_session() class Node(object): def __repr__(self): return %s %s % (self.__class__.__name__, self.name) nodeTable = Table( 'node', metadata, Column('node_id', Integer, primary_key=True, unique=True), Column('name', String(255), unique=True), Column('console_id', Integer, ForeignKey('node.node_id')), Column('switch_id', Integer, ForeignKey('node.node_id')), ) mapper (Node, nodeTable, properties = { 'id': nodeTable.c.node_id, 'console': relation( Node, primaryjoin = nodeTable.c.console_id == nodeTable.c.node_id, remote_side = [nodeTable.c.node_id], backref = 'consoleNodes', ), 'switch': relation( Node, primaryjoin = nodeTable.c.switch_id == nodeTable.c.node_id, remote_side = [nodeTable.c.node_id], backref = 'switchNodes', ), }, ) rows = ( { 'node_id': 1, 'name': 'console1..com', 'console_id': None, 'switch_id': 2 }, { 'node_id': 2, 'name': 'switch1..com', 'console_id': 1, 'switch_id': None }, { 'node_id': 3, 'name': 'node1..com', 'console_id': 1, 'switch_id': 2 }, { 'node_id': 4, 'name': 'node2..com', 'console_id': 1, 'switch_id': 2 }, { 'node_id': 5, 'name': 'node3..com', 'console_id': 1, 'switch_id': 2 }, { 'node_id': 6, 'name': 'node4..com', 'console_id': 1, 'switch_id': 2 }, { 'node_id': 7, 'name': 'node5..com', 'console_id': 1, 'switch_id': 2 }, ) nodeTable.create() i = nodeTable.insert() for row in rows: print row i.execute(**row) # now query query = session.query(Node) console = query.select_by(name='console1..com')[0] print console.consoleNodes # Isn't this a valid use of select_by with the relation mapper above ? print query.select_by(console=console) # trying to get list of rows/Node instances where console_id = console.node_id # given console node name, preferably in one step. # I need to chain such conditions depending on the argument. query.join('consoleNodes').select_by(name='console1..com') --~--~-~--~~~---~--~~ You 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: mssql using pymssql 0.8 and sqlalchemy 0.3.6
pyodbc seems to do the trick. Thanks for the recommendation. I am having problem selecting from views in ms sql database, it returns 0 rows, using the same statement in enterprise manager returns a bunch of rows. Is there anything special I need to do for selecting data from views? On Mar 28, 1:01 pm, Rick Morrison [EMAIL PROTECTED] wrote: DBlib is deprecated by MS, and it hasn't been updated in like five years, and is just never going to be updated ever. If you can't change the name of the database, then I would take a look at replacing pymssql with pyodbc, I have heard of people having good luck with it (Paul, want to jump in here?) Rick On 3/28/07, Lee Connell [EMAIL PROTECTED] wrote: There is a fix for column names, however I don't see anything to overcome this issue if the database name is more than 30 chars? Any suggestions? On Mar 28, 12:44 pm, Lee Connell [EMAIL PROTECTED] wrote: the table I'm trying to grab is under 30 chars. Is there a way to change this limit? On Mar 28, 12:23 pm, Rick Morrison [EMAIL PROTECTED] wrote: Pymssql uses DBlib under the covers, and there's a 30-character identifier limit in DBlib. That limit applies to any identifier, including table and column names, which might explain your second issue. Rick On 3/28/07, Lee Connell [EMAIL PROTECTED] wrote: I am using these tools on a windows machine. Some problems I ran into. First of all I can't connect to a database that's name is more than 30 chars long. Error returned says it can't find the database and the database it's looking for has been truncated. When I connect to a database less than 30 chars long, I try to load a table and it complains that it cannot find the table. The table is definitely there and I've tried many different table names as well that are available in the DB. Anyone know of a fix or is this a bug? ### Here is my code. # from sqlalchemy import * db_name = this_is_a_test_of_a_long_database_string db_user = lee db_pass = db_conn = mssql://%s:[EMAIL PROTECTED]/%s % (db_user, db_pass, db_name) db = create_engine(db_conn, echo=True) metadata = BoundMetaData(db) users_table = Table(syscolumns, metadata, autoload=True) list(users_table.columns)[0].name # Ammonoosuc_Computer_Services_MSCRM # FilteredServiceAppointment --~--~-~--~~~---~--~~ You 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: mssql using pymssql 0.8 and sqlalchemy 0.3.6
As far as I know a view is treated like a table in SA - if you're getting the query to run at all, it's most likely that SA is issuing a different query that what you thought it might. Either use the SQL profiler in MSSQL to see the actual SQL going over the wire, or turn on logging in SA to see what queries are being issued. Odds are you're sending two different queries. On 3/28/07, Lee Connell [EMAIL PROTECTED] wrote: pyodbc seems to do the trick. Thanks for the recommendation. I am having problem selecting from views in ms sql database, it returns 0 rows, using the same statement in enterprise manager returns a bunch of rows. Is there anything special I need to do for selecting data from views? On Mar 28, 1:01 pm, Rick Morrison [EMAIL PROTECTED] wrote: DBlib is deprecated by MS, and it hasn't been updated in like five years, and is just never going to be updated ever. If you can't change the name of the database, then I would take a look at replacing pymssql with pyodbc, I have heard of people having good luck with it (Paul, want to jump in here?) Rick On 3/28/07, Lee Connell [EMAIL PROTECTED] wrote: There is a fix for column names, however I don't see anything to overcome this issue if the database name is more than 30 chars? Any suggestions? On Mar 28, 12:44 pm, Lee Connell [EMAIL PROTECTED] wrote: the table I'm trying to grab is under 30 chars. Is there a way to change this limit? On Mar 28, 12:23 pm, Rick Morrison [EMAIL PROTECTED] wrote: Pymssql uses DBlib under the covers, and there's a 30-character identifier limit in DBlib. That limit applies to any identifier, including table and column names, which might explain your second issue. Rick On 3/28/07, Lee Connell [EMAIL PROTECTED] wrote: I am using these tools on a windows machine. Some problems I ran into. First of all I can't connect to a database that's name is more than 30 chars long. Error returned says it can't find the database and the database it's looking for has been truncated. When I connect to a database less than 30 chars long, I try to load a table and it complains that it cannot find the table. The table is definitely there and I've tried many different table names as well that are available in the DB. Anyone know of a fix or is this a bug? ### Here is my code. # from sqlalchemy import * db_name = this_is_a_test_of_a_long_database_string db_user = lee db_pass = db_conn = mssql://%s:[EMAIL PROTECTED]/%s % (db_user, db_pass, db_name) db = create_engine(db_conn, echo=True) metadata = BoundMetaData(db) users_table = Table(syscolumns, metadata, autoload=True) list(users_table.columns)[0].name # Ammonoosuc_Computer_Services_MSCRM # FilteredServiceAppointment --~--~-~--~~~---~--~~ You 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: UOW relation delete bug
are you sure thats right ? ClauseParameters doesnt have any kind of __getattr__ logic going oni think the test you have there would return False in all cases. are you sure you dont mean: self.IINSERT = tbl.has_sequence.key in parameters[0] has_key() has been removed in favor of just __contains__() since thats where py2.6/3000 is headed. On Mar 28, 2007, at 3:16 PM, Rick Morrison wrote: The MSSQL module examines the parameter object, looking for whether or not the query being executed has an explicit primary key on an autoincrementing column. Inserting those things in MSSQL is a special mode (don't get me started on how goofy that is...). The code was using key in parmobject to look for it; I changed it to hasattr(), and it seems fine. Thanks for the explanation. Rick On 3/28/07, Michael Bayer [EMAIL PROTECTED] wrote: On Mar 28, 1:15 pm, Rick Morrison [EMAIL PROTECTED] wrote: Hey Mike, this looks to be related to the parameters-as- ClauseParameters instead of Python dict() on a different thread. you mean the thing i just checked in yesterday ? OK yeah, youve always been getting a ClauseParameters object, its just it subclassed dict. I removed that becuase the API of ClauseParameters was getting totally muddy and i didnt even understand how it worked anymore. so now its more explicit fields with their behaviors more clearly separated. but it still has a __getitem__ and a __contains__ on it and we can put keys() there as well, so what more dictlike behavior do you need ? I'm going to need some help or advice beating the MSSQL module into shape with the new convention. Where does the positional / non-positional specification go? I don't see it in any of the DB modules. we are usually calling paramstyle off the DBAPI itself to figure that out. that might have to change soon when I address the ImportError ticket. --~--~-~--~~~---~--~~ You 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: UOW relation delete bug
Working now... Anyway, wouldn't this operation be a lot more efficient using IN() instead of executemany()? Is detecting that too hard? Rick On 3/28/07, Michael Bayer [EMAIL PROTECTED] wrote: it works for me, the bind params are in sqlite: [[1], [3], [5]] in postgres: [{'id': 1}, {'id': 3}, {'id': 5}] in both cases, thats a list of three sets of bind params, one positional and the other named, which correspond to executemany(). if this condition doesnt work with MS-SQL, MS-SQL should get added to test/engine/execute.py, which test the various scenarios of *multiparams and **params that you can send to execute(). just pick the paramstyle that works with MS-SQL and add it to the supported list for that test. On Mar 28, 2007, at 1:36 AM, Rick Morrison wrote: Surprised no one has hit this one yet. When issuing a series of deletes in a UOW, SA issues the bogus delete statement DELETE child where id = [1,2,3] instead of using IN() Test case attached. Seems to work in Sqlite even while issuing the bogus SQL (which is probably why a unit test didn't pick it up), but MS-SQL doesn't like it; didn't check PG or others. from sqlalchemy import * import logging logging.basicConfig() logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO) #metadata = BoundMetaData('mssql://d:[EMAIL PROTECTED]/drvtest') metadata = BoundMetaData('sqlite:///:memory:') entity = Table('entity', metadata, Column('id', INT, primary_key=True, nullable=False), Column('typ', VARCHAR(12)), Column('lname', VARCHAR(128)) ) entityattr = Table('entityattr', metadata, Column('id', INT, primary_key=True, nullable=False), Column('ident', INT, ForeignKey('entity.id'), nullable=False), Column('typ', VARCHAR(12), nullable=False), Column('val', VARCHAR(128)) ) metadata.create_all() class O(object): def __init__(self,**kw): for k,v in kw.items(): setattr(self,k,v) class Ent(O): pass class Entattr(O): pass mapper(Ent, entity, properties = {'props':relation(Entattr, cascade=all, delete-orphan)}) mapper(Entattr, entityattr) S = create_session() S.save(Ent(typ='A',lname='A', props = [Entattr(typ='A1', val='1'), Entattr(typ='A2', val='2'), Entattr(typ='A3', val='3'), Entattr(typ='A4', val='4'), Entattr(typ='A5', val='5'), Entattr(typ='A6', val='6') ])) S.flush() S.clear() e = S.query(Ent).options(eagerload('props')).select()[0] # remove some attributes e.props = [p for p in e.props if 0 == int(p.val) % 2] # put some back e.props.append(Entattr(typ='A6', val='6')) e.props.append(Entattr(typ='A7', val='7')) e.props.append(Entattr(typ='A8', val='8')) S.flush()# -- Delete issued here S.clear() e = S.query(Ent).options(eagerload('props')).select()[0] assert 6 == len(e.props) metadata.drop_all() --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: UOW relation delete bug
I doubt theres any performance difference if the DBAPI does the right thing with a prepared statement. also, IN() wont work too well if the rows are targeted by more than just one column; plus it generally limits to 1000 elements and presents a larger and non-consistent string to the DB which has to re-parse it each time. On Mar 28, 2007, at 4:44 PM, Rick Morrison wrote: Working now... Anyway, wouldn't this operation be a lot more efficient using IN() instead of executemany()? Is detecting that too hard? Rick On 3/28/07, Michael Bayer [EMAIL PROTECTED] wrote: it works for me, the bind params are in sqlite: [[1], [3], [5]] in postgres: [{'id': 1}, {'id': 3}, {'id': 5}] in both cases, thats a list of three sets of bind params, one positional and the other named, which correspond to executemany(). if this condition doesnt work with MS-SQL, MS-SQL should get added to test/engine/execute.py, which test the various scenarios of *multiparams and **params that you can send to execute(). just pick the paramstyle that works with MS-SQL and add it to the supported list for that test. On Mar 28, 2007, at 1:36 AM, Rick Morrison wrote: Surprised no one has hit this one yet. When issuing a series of deletes in a UOW, SA issues the bogus delete statement DELETE child where id = [1,2,3] instead of using IN() Test case attached. Seems to work in Sqlite even while issuing the bogus SQL (which is probably why a unit test didn't pick it up), but MS-SQL doesn't like it; didn't check PG or others. from sqlalchemy import * import logging logging.basicConfig() logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO) #metadata = BoundMetaData('mssql://d:[EMAIL PROTECTED]/drvtest') metadata = BoundMetaData('sqlite:///:memory:') entity = Table('entity', metadata, Column('id', INT, primary_key=True, nullable=False), Column('typ', VARCHAR(12)), Column('lname', VARCHAR(128)) ) entityattr = Table('entityattr', metadata, Column('id', INT, primary_key=True, nullable=False), Column('ident', INT, ForeignKey(' entity.id'), nullable=False), Column('typ', VARCHAR(12), nullable=False), Column('val', VARCHAR(128)) ) metadata.create_all() class O(object): def __init__(self,**kw): for k,v in kw.items(): setattr(self,k,v) class Ent(O): pass class Entattr(O): pass mapper(Ent, entity, properties = {'props':relation(Entattr, cascade=all, delete-orphan)}) mapper(Entattr, entityattr) S = create_session() S.save(Ent(typ='A',lname='A', props = [Entattr(typ='A1', val='1'), Entattr(typ='A2', val='2'), Entattr(typ='A3', val='3'), Entattr(typ='A4', val='4'), Entattr(typ='A5', val='5'), Entattr(typ='A6', val='6') ])) S.flush() S.clear() e = S.query(Ent).options(eagerload('props')).select()[0] # remove some attributes e.props = [p for p in e.props if 0 == int(p.val) % 2] # put some back e.props.append(Entattr(typ='A6', val='6')) e.props.append(Entattr(typ='A7', val='7')) e.props.append(Entattr(typ='A8', val='8')) S.flush()# -- Delete issued here S.clear() e = S.query(Ent).options(eagerload('props')).select()[0] assert 6 == len(e.props) metadata.drop_all () --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: func() bug ?
Hi, any(:any) = :a_1 it should be :a_1 = any(:any) This looks like odd Postgres behaviour, the equals operator not quite being commutative. We could add a Postgres-specifc workaround, in PGCompiler something like (untested): def visit_binary(self, binary): if isinstance(binary.left, sql._Function) and binary.left.name.lower() == 'any' and binary.operator == '=': binary.left, binary.right = binary.right, binary.left super(PGCompiler, self).visit_binary(binary) The MSSQL dialect uses a similar trick to work around some adodbapi bugs. Paul --~--~-~--~~~---~--~~ You 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: Automatic generation of changelog
dont have an example handy, but yeah youd want to make a MapperExtension and work into the after_insert(), after_update() and after_delete() hooks (or maybe the before_ versions of each one, depending on how you detect changes). you can issue writes to the database immediately within those and theyll be within the current transaction. theres an example of a write side MapperExtension in examples/pickle/ custom_pickler.py . if you want some help on actually detecting whats changed, you can use some features of the attributes package to do so. if you have an instance of MyClass and want to inspect the history of instance.someattribute: history = MyClass.someattribute.get_history(instance, passive=True) passive=True means dont fire off lazy loaders. that call returns to you an AttributeHistory object, with which you can say: history.is_modified() history.added_items() - returns a list of new values, a one-element list for scalar attributes history.deleted_items() - returns a list of deleted values, a one - element list for scalar attributes history.unchanged_items() - etc note that by history, we mean things that have occured since the instance was loaded from the database into the current session. On Mar 28, 5:39 pm, Arnar Birgisson [EMAIL PROTECTED] wrote: Hi there, I have an old system that I'm porting over to SA. In the old system there is one entity that keeps a change history of itself. In the code that performs db updates, the current state of the object is examined and before it is updated I insert rows to a table with colums like this: object id change-event-id fieldname old-value new-value This is used to render a change history of the entity to the user. Now, can I automate this somehow with SA? Preferably I'd like to do this automatically on object update. Can I use the dirty set in the session to find out what columns of the mapped table have changed? How do I hook into the update action - I think I need a mapper extension, but can you point me to some examples? Has anyone done something similar (the whole changelog thing) with SA? Arnar --~--~-~--~~~---~--~~ You 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: Automatic generation of changelog
Hi Dave, Thank you very much, seems I should be able to do what I want. I'll take a stab at it tomorrow and report. On 3/28/07, Michael Bayer [EMAIL PROTECTED] wrote: note that by history, we mean things that have occured since the instance was loaded from the database into the current session. That history is cleared on session.flush() - right? Arnar --~--~-~--~~~---~--~~ You 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
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). 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
[sqlalchemy] Re: UOW relation delete bug
yikes, you're right - fixed in rev 2458. thanks for having a look. On 3/28/07, Michael Bayer [EMAIL PROTECTED] wrote: are you sure thats right ? ClauseParameters doesnt have any kind of __getattr__ logic going oni think the test you have there would return False in all cases. are you sure you dont mean: self.IINSERT = tbl.has_sequence.key in parameters[0] has_key() has been removed in favor of just __contains__() since thats where py2.6/3000 is headed. On Mar 28, 2007, at 3:16 PM, Rick Morrison wrote: The MSSQL module examines the parameter object, looking for whether or not the query being executed has an explicit primary key on an autoincrementing column. Inserting those things in MSSQL is a special mode (don't get me started on how goofy that is...). The code was using key in parmobject to look for it; I changed it to hasattr(), and it seems fine. Thanks for the explanation. Rick On 3/28/07, Michael Bayer [EMAIL PROTECTED] wrote: On Mar 28, 1:15 pm, Rick Morrison [EMAIL PROTECTED] wrote: Hey Mike, this looks to be related to the parameters-as-ClauseParameters instead of Python dict() on a different thread. you mean the thing i just checked in yesterday ? OK yeah, youve always been getting a ClauseParameters object, its just it subclassed dict. I removed that becuase the API of ClauseParameters was getting totally muddy and i didnt even understand how it worked anymore. so now its more explicit fields with their behaviors more clearly separated. but it still has a __getitem__ and a __contains__ on it and we can put keys() there as well, so what more dictlike behavior do you need ? I'm going to need some help or advice beating the MSSQL module into shape with the new convention. Where does the positional / non-positional specification go? I don't see it in any of the DB modules. we are usually calling paramstyle off the DBAPI itself to figure that out. that might have to change soon when I address the ImportError ticket. --~--~-~--~~~---~--~~ You 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: Automatic generation of changelog
On Mar 28, 2007, at 6:07 PM, Arnar Birgisson wrote: Hi Dave, Thank you very much, seems I should be able to do what I want. I'll take a stab at it tomorrow and report. On 3/28/07, Michael Bayer [EMAIL PROTECTED] wrote: note that by history, we mean things that have occured since the instance was loaded from the database into the current session. That history is cleared on session.flush() - right? yes --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---