> The database is part of a desktop accounting application running on
> Windows. I'm writing a program to interface with it, to automate
> adding documents.
>
> The idea was that it would be run once a month to add a bunch of
> invoices. The backup would run before this operation, in case
> something unexpected goes wrong.
>
> Reducing the scope of the program, and dealing with backups separately
> does sound like a better idea.
engine.execute() is equivalent to:
conn = dbapi.connect(...)
cursor = conn.cursor()
cursor.execute(<statement>)
< possibly call conn.commit() here if the statement qualifies for autocommit>
return cursor via ResultProxy()
cursor.close()/conn.close() when ResultProxy is closed, automatic if no cursor.description was present.
your examples with pyodbc indicate pyodbc is a little conflicted how to handle this. The nonstandard conn.execute() call seems to fail if Pyodbc's "autocommit" (note this is entirely distinct from the SQLAlchemy engine autocommit feature) is not enabled, yet your SQLAlchemy script didn't throw this error when using cursor.execute() (where again the pyodbc autocommit flag remains at false unless you modified it yourself).
If the "commit" call is required then you'd need to be using engine.connect().execution_options(autocommit=True).execute(my statement). The BACKUP command doesn't trigger autocommit, so I'm not sure how your SQL log ended up generating a COMMIT statement.
> --
> You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
> To post to this group, send email to sqlal...@googlegroups.com.
> To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
>
Oops, I was trying it with
engine.connect().execution_options(autocommit=True).execute as well,
and didn't notice there was a difference in the echo when editing the
pastebin. There's of course no COMMIT at the end with eng.execute().
I've updated pastebin with both versions.
The behaviour doesn't change though. In both cases, if the file
doesn't exist, it doesn't exist after finishing the BACKUP. If an
empty file already exists, _even without the COMMIT_, the server still
writes 2KB to it.
As for the autocommit error, the server complains about doing a backup
within a transaction. I'm guessing sqlalchemy's engine.execute()
doesn't automatically start a transaction, while pyodbc's
conn.execute() without autocommit does start a transaction.
If you try to run a BACKUP via pyodbc, the cursor.execute() call starts and finishes with no error, but the backup doesn’t get made. With help from CubicWeb‘s post MS SQL Server Backuping gotcha, I learned that BACKUP and RESTOREs over ODBC trigger some kind of asynchronous / multiple result set mode.
I'm guessing sqlalchemy closes the cursor before the server can finish
the backup?