Context manager for database connection
dn
PythonList at DancesWithMice.info
Wed Aug 23 14:11:02 EDT 2023
On 24/08/2023 03.41, Jason Friedman via Python-list wrote:
> I want to be able to write code like this:
>
> with Database() as mydb:
> conn = mydb.get_connection()
> cursor = conn.get_cursor()
> cursor.execute("update table1 set x = 1 where y = 2")
> cursor.close()
> cursor = conn.get_cursor()
> cursor.execute("update table2 set a = 1 where b = 2")
> cursor.close()
>
> I'd like for both statements to succeed and commit, or if either fails to
> stop and for all to rollback.
>
> Is what I have below correct?
>
>
> import jaydebeapi as jdbc
> class Database:
> database_connection = None
>
> def __init__(self, auto_commit: bool = False):
> self.database_connection = jdbc.connect(...)
> self.database_connection.jconn.setAutoCommit(auto_commit)
>
> def __enter__(self) -> jdbc.Connection:
> return self
>
> def __exit__(self, exception_type: Optional[Type[BaseException]],
> exception_value: Optional[BaseException],
> traceback: Optional[types.TracebackType]) -> bool:
> if exception_type:
> self.database_connection.rollback()
> else:
> self.database_connection.commit()
> self.database_connection.close()
>
> def get_connection(self) -> jdbc.Connection:
> return self.database_connection
Looking good!
Assuming this is the only DB-interaction, a context-manager seems
appropriate. If the real use-case calls for more interactions, the cost
of establishing and breaking DB-connections becomes a consideration.
Alternately, the 'length'?'life' of the context-manager *might*
complicate things.
Intriguing that given such a start, the code doesn't feature a
context-manager for a query.
That two cursors are established is also a 'cost'. Could both queries
utilise the same cursor?
(in which case, could consider adding to __init__() or __enter__(), and
close in __exit__() )
Because the context-manager has been implemented as a class, there is no
reason why one can't add more methods to that class (it doesn't need to
be limited to the functional __enter__() and __exit__() methods!
Indeed there is already get_connection(). Why not also a query( self,
sql-code ) method?
These might reduce the mainline-code to something like:
if __name__ == "__main__":
with Database() as mydb:
mydb.query( "update table1 set x = 1 where y = 2" )
mydb.query( "update table2 set a = 1 where b = 2" )
--
Regards,
=dn
More information about the Python-list
mailing list