Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sqlalchemy: stopping a long-running query

I have a seemingly straight-forward situation, but can't find a straight-forward solution.

I'm using sqlalchemy to query postgres. If a client timeout occurs, I'd like to stop/cancel the long running postgres queries from another thread. The thread has access to the Session or Connection object.

At this point I've tried:

session.bind.raw_connection().close()

and

session.connection().close()

and

session.close

and

session.transaction.close()

But no matter what I try, the postgres query still continues until it's end. I know this from watching pg in top. Shouldn't this be fairly easy to do? I'm I missing something? Is this impossible without getting the pid and sending a stop signal directly?

like image 963
Cody Django Avatar asked Feb 24 '12 20:02

Cody Django


People also ask

How make SQLAlchemy faster?

Instead of returning entire model instances, SQLAlchemy can fetch only the columns we're interested in. This not only reduces the amount of data sent, but also avoids the need to instantiate entire objects. Working with tuples of column data instead of models can be quite a bit faster.

What is lazy dynamic SQLAlchemy?

Lazy parameter determines how the related objects get loaded when querying through relationships. Below listed are the four main lazy parameters. Typically when you query the database, the data get loaded at once; however, lazy parameter allows you to alternate the way they get loaded. lazy = 'select' (or True)

What is lazy loading SQLAlchemy?

Lazy loading refers to objects are returned from a query without the related objects loaded at first. When the given collection or reference is first accessed on a particular object, an additional SELECT statement is emitted such that the requested collection is loaded.

Is SQLAlchemy efficient?

SQLAlchemy leverages powerful common statements and types to ensure its SQL statements are crafted efficiently and properly for each database type and vendor without you having to think about it. This makes it easy to migrate logic from Oracle to PostgreSQL or from an application database to a data warehouse.


1 Answers

This seems to work well, so far:

def test_close_connection(self):
    import threading
    from psycopg2.extensions import QueryCanceledError
    from sqlalchemy.exc import DBAPIError

    session = Session()
    conn = session.connection()
    sql = self.get_raw_sql_for_long_query()

    seconds = 5
    t = threading.Timer(seconds, conn.connection.cancel)
    t.start()

    try:
        conn.execute(sql)
    except DBAPIError, e:
        if type(e.orig) == QueryCanceledError:
            print 'Long running query was cancelled.'
    t.cancel()

source

like image 114
Cody Django Avatar answered Oct 17 '22 07:10

Cody Django