On Aug 18, 2011, at 1:06 PM, Massi wrote:

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

It's just checking if theres a RETURNING clause added, which your clause does 
not yet support.  Add _returning = False to your construct for now.




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

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

Reply via email to