I am using sqlalchemy and sqlalchemy-teradata to query on my database. Every select statement generated by sqlalchemy would generate a table lock which impacts other concurrent users who cannot perform any insert, update or delete operation on the table while the previous user is reading it. To avoid such table locks, I need to add the following string before the SELECT statement:
LOCK ROW FOR ACCESS
SELECT * FROM DATABASE.TABLE;
How can I override sqlalchemy select statements to add this string? Note that I have also raised the issue on GitHub here but did not find any solution so far: https://github.com/Teradata/sqlalchemy-teradata/issues/39
[Update]
When connecting to Teradata, I have added the statement provided below by dnoeth:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base, DeferredReflection
from sqlalchemy.orm import scoped_session, sessionmaker
[...]
engine = create_engine('teradata://' + user + ':' + password + '@' + host + ':22/' + database)
db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
db_session.execute('SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;') # To avoid locking tables when doing select on tables
Base = declarative_base(cls=DeferredReflection)
Base.query = db_session.query_property()
But now I have the following error message when SQLAlchemy tries to read Teradata meta data:
sqlalchemy.exc.DatabaseError: (teradata.api.DatabaseError) (3932, '[25000] [Teradata][ODBC Teradata Driver][Teradata Database] Only an ET or null statement is legal after a DDL Statement. ') [SQL: 'SELECT columnname, columntype, columnlength, chartype, decimaltotaldigits, decimalfractionaldigits, columnformat, nullable, defaultvalue, idcoltype \nFROM dbc.ColumnsV \nWHERE DatabaseName=? AND TableName=?'] [parameters: ('dev_migration_tool', 'migration_object_type')]
lock row for accessand use that in your query. - ULickSET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;within your session once. Then the default lock will switch to ACCESS instead of READ. - dnoethSET SESSIONis considered a DDL statement, which must be commited. AddingCOMMIT;should resolve the issue. - dnoeth