I changed the code to (SA 0.7.2 with pyodbc2.1.9): class InsertFromSelect(Executable, ClauseElement) : _execution_options =\ Executable._execution_options.union({'autocommit': True}) def __init__(self, table, select) : self.table = table self.select = select
@compiler.compiles(InsertFromSelect, "mssql") def visit_insert_from_select(element, compiler, **kw) : compiler.isinsert = True compiler._mssql_requires_identity_insert = True tab_name = compiler.process(element.table, asfrom=True) q = "INSERT INTO %s (%s) %s;" % (tab_name, ', '.join([compiler.process(c) for c in element.table.c]), compiler.process(element.select)) return q applied the patch and I got the following error: File "C:\Python26\lib\site-packages\sqlalchemy-0.7.2-py2.6-win32.egg \sqlalchemy\engine\base.py", line 2285, in execute return connection.execute(statement, *multiparams, **params) File "C:\Python26\lib\site-packages\sqlalchemy-0.7.2-py2.6-win32.egg \sqlalchemy\engine\base.py", line 1399, in execute params) File "C:\Python26\lib\site-packages\sqlalchemy-0.7.2-py2.6-win32.egg \sqlalchemy\engine\base.py", line 1532, in _execute_clauseelement compiled_sql, distilled_params File "C:\Python26\lib\site-packages\sqlalchemy-0.7.2-py2.6-win32.egg \sqlalchemy\engine\base.py", line 1599, in _execute_context None, None) File "C:\Python26\lib\site-packages\sqlalchemy-0.7.2-py2.6-win32.egg \sqlalchemy\engine\base.py", line 1595, in _execute_context context = constructor(dialect, self, conn, *args) File "C:\Python26\lib\site-packages\sqlalchemy-0.7.2-py2.6-win32.egg \sqlalchemy\engine\default.py", line 418, in _init_compiled self._is_explicit_returning = compiled.statement._returning StatementError: 'InsertFromSelect' object has no attribute '_returning' (original cause: AttributeError: 'InsertFromSelect' object has no attribute '_returning') 'INSERT INTO...' On 18 Ago, 18:34, Michael Bayer <mike...@zzzcomputing.com> wrote: > On Aug 18, 2011, at 12:24 PM, Massi wrote: > > > > > > > > > > > Hi everyone, I'm trying to implement an InsertFromSelect workaround to > > handle the identity insert issue of SQL server. This is more or less > > what I'm doing: > > > class InsertFromSelect(Executable, ClauseElement) : > > def __init__(self, table, select) : > > self.table = table > > self.select = select > > > @compiler.compiles(InsertFromSelect, "mssql") > > def visit_insert_from_select(element, compiler, **kw) : > > tab_name = compiler.process(element.table, asfrom=True) > > q = "SET IDENTITY_INSERT %s ON;" %(tab_name) > > q += "INSERT INTO %s (%s) %s;" % (tab_name, > > ', '.join([compiler.process(c) for c in element.table.c]), > > compiler.process(element.select)) > > q += "SET IDENTITY_INSERT %s OFF;" %(tab_name) > > return q > > it would be better to use the built in IDENTITY_INSERT facilities of the > MSSQL dialect itself. > > Set the "isinsert" flag on your compiled object, and also set a new flag I > can add called "_mssql_requires_identity_insert": > > @compiler.compiles(InsertFromSelect, "mssql") > def visit_insert_from_select(element, compiler, **kw) : > compiler.isinsert = True > compiler._mssql_requires_identity_insert = True > > patch for testing: > > diff -r 44e239751af8 lib/sqlalchemy/dialects/mssql/base.py > --- a/lib/sqlalchemy/dialects/mssql/base.py Wed Aug 17 14:55:21 2011 -0400 > +++ b/lib/sqlalchemy/dialects/mssql/base.py Thu Aug 18 12:32:22 2011 -0400 > @@ -655,7 +655,9 @@ > seq_column = tbl._autoincrement_column > insert_has_sequence = seq_column is not None > > - if insert_has_sequence: > + if getattr(self.compiled._mssql_requires_identity_insert, False): > + self._enable_identity_insert = True > + elif insert_has_sequence: > self._enable_identity_insert = \ > seq_column.key in self.compiled_parameters[0] > else: > > if this works for you I can commit it with a short test and it will be in > 0.7.3. > > > > > insert_from_select = InsertFromSelect(new_table, old_table)) > > engine.execute(insert_from_select) > > easier issue here, your construct also needs "autocommit" enabled if you are > going to use connectionless execution: > > class InsertFromSelect(...): > _execution_options = \ > Executable._execution_options.union({'autocommit': True}) > > or better yet just subclass UpdateBase instead of (Executable, ClauseElement). > > will add a doc -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.