Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/cardinal_pythonlib/sqlalchemy/sqlserver.py : 41%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/env python
2# cardinal_pythonlib/sqlalchemy/sqlserver.py
4"""
5===============================================================================
7 Original code copyright (C) 2009-2021 Rudolf Cardinal (rudolf@pobox.com).
9 This file is part of cardinal_pythonlib.
11 Licensed under the Apache License, Version 2.0 (the "License");
12 you may not use this file except in compliance with the License.
13 You may obtain a copy of the License at
15 https://www.apache.org/licenses/LICENSE-2.0
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
23===============================================================================
25**SQLAlchemy functions specific to Microsoft SQL Server.**
27"""
29from contextlib import contextmanager
31from sqlalchemy.orm import Session as SqlASession
33from cardinal_pythonlib.sqlalchemy.dialect import quote_identifier
34from cardinal_pythonlib.sqlalchemy.engine_func import is_sqlserver
35from cardinal_pythonlib.sqlalchemy.session import get_engine_from_session
38# =============================================================================
39# Workarounds for SQL Server "DELETE takes forever" bug
40# =============================================================================
42@contextmanager
43def if_sqlserver_disable_constraints(session: SqlASession,
44 tablename: str) -> None:
45 """
46 If we're running under SQL Server, disable constraint checking for the
47 specified table while the resource is held.
49 Args:
50 session: SQLAlchemy :class:`Session`
51 tablename: table name
53 See
54 https://stackoverflow.com/questions/123558/sql-server-2005-t-sql-to-temporarily-disable-a-trigger
55 """ # noqa
56 engine = get_engine_from_session(session)
57 if is_sqlserver(engine):
58 quoted_tablename = quote_identifier(tablename, engine)
59 session.execute(
60 f"ALTER TABLE {quoted_tablename} NOCHECK CONSTRAINT all")
61 yield
62 session.execute(
63 f"ALTER TABLE {quoted_tablename} WITH CHECK CHECK CONSTRAINT all")
64 else:
65 yield
68@contextmanager
69def if_sqlserver_disable_triggers(session: SqlASession,
70 tablename: str) -> None:
71 """
72 If we're running under SQL Server, disable triggers for the specified table
73 while the resource is held.
75 Args:
76 session: SQLAlchemy :class:`Session`
77 tablename: table name
79 See
80 https://stackoverflow.com/questions/123558/sql-server-2005-t-sql-to-temporarily-disable-a-trigger
81 """ # noqa
82 engine = get_engine_from_session(session)
83 if is_sqlserver(engine):
84 quoted_tablename = quote_identifier(tablename, engine)
85 session.execute(
86 f"ALTER TABLE {quoted_tablename} DISABLE TRIGGER all")
87 yield
88 session.execute(
89 f"ALTER TABLE {quoted_tablename} ENABLE TRIGGER all")
90 else:
91 yield
94@contextmanager
95def if_sqlserver_disable_constraints_triggers(session: SqlASession,
96 tablename: str) -> None:
97 """
98 If we're running under SQL Server, disable triggers AND constraints for the
99 specified table while the resource is held.
101 Args:
102 session: SQLAlchemy :class:`Session`
103 tablename: table name
104 """
105 with if_sqlserver_disable_constraints(session, tablename):
106 with if_sqlserver_disable_triggers(session, tablename):
107 yield