SQLAlchemy engine.execute() leaves a connection to the database in sleeping status

十年热恋 提交于 2020-01-25 07:53:09

问题


I am using SQL server database. I've noticed that when executing the code below, I get a connection to the database left over in 'sleeping' state with an 'AWAITING COMMAND' status.

    engine = create_engine(url, connect_args={'autocommit': True})
    res = engine.execute(f"CREATE DATABASE my_database")
    res.close()
    engine.dispose()

With a breakpoint after the engine.dispose() call, I can see an entry on the server in the EXEC sp_who2 table. This entry only disappears after I kill the process.


回答1:


Probably Connection Pooling

Connection Pooling

A connection pool is a standard technique used to maintain long running connections in memory for efficient re-use, as well as to provide management for the total number of connections an application might use simultaneously.

Particularly for server-side web applications, a connection pool is the standard way to maintain a “pool” of active database connections in memory which are reused across requests.

SQLAlchemy includes several connection pool implementations which integrate with the Engine. They can also be used directly for applications that want to add pooling to an otherwise plain DBAPI approach.

.

I'm not sure if this is what gets in the way of my teardown method which drops the database

To drop a database that's possibly in use try:

USE master;
ALTER DATABASE mydb SET RESTRiCTED_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE mydb;



回答2:


You basically want to kill all the connections You could use something like this:

For MS SQL Server 2012 and above

USE [master];

DECLARE @kill varchar(8000) = '';  
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), session_id) + ';'  
FROM sys.dm_exec_sessions
WHERE database_id  = db_id('MyDB')

EXEC(@kill);

For MS SQL Server 2000, 2005, 2008

USE master;

DECLARE @kill varchar(8000); SET @kill = '';  
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), spid) + ';'  
FROM master..sysprocesses  
WHERE dbid = db_id('MyDB')

EXEC(@kill); 

Or something more script-like:

DECLARE @pid SMALLINT, @sql NVARCHAR(100)
DECLARE curs CURSOR LOCAL FORWARD_ONLY FOR
  SELECT DISTINCT pid FROM master..sysprocesses where dbid = DB_ID(@dbname)
OPEN curs
fetch next from curs into @pid
while @@FETCH_STATUS = 0
BEGIN
    SET @sql = 'KILL ' + CONVERT(VARCHAR, @pid)
    EXEC(@sql)
    FETCH NEXT FROM curs into @pid
END
CLOSE curs
DEALLOCATE curs

More can be found here: Script to kill all connections to a database (More than RESTRICTED_USER ROLLBACK)



来源:https://stackoverflow.com/questions/58559883/sqlalchemy-engine-execute-leaves-a-connection-to-the-database-in-sleeping-stat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!