Таймаут спорадического семафора с использованием SQL Server 2014 и pyodbc - PullRequest
0 голосов
/ 16 мая 2019

У меня странная проблема с тайм-аутом семафора при вставке в SQL Server.Ниже приведен небольшой фрагмент кода, который может воспроизвести проблему.

Ни у одного из моих коллег, использующих ту же базу кода, не было проблем с базой данных.У нас также есть сервер приложений, который может часами без проблем оставаться на связи с базой данных.На моем ноутбуке работают разные вещи: 1) у меня установлена ​​новейшая версия Dell Precision 5530, которая отличается от моих коллег;2) Я использую последнюю версию Anaconda / Python 3.7 / pyodbc 4.0.26 / Windows 10, в то время как мои коллеги работают на python 3.5 / 3.6 / Windows 7 & Linux.Погуглил, предложил попробовать обновить драйвер сетевого адаптера, который я пробовал, и использую последнюю версию драйвера.

Кто-нибудь видел подобную проблему?

[ПРАВИТЬ 1] Благодаря приведенным ниже рекомендациям я обновил драйвер до новой версии с другой ошибкой.

import time
import pyodbc

cxn = pyodbc.connect('DSN=db;DATABASE=db;Uid=user;Pwd=password', autocommit=True)

def insert(cxn):
    ids = [(i, ) for i in range(100000)]
    cur = cxn.cursor()
    cur.fast_executemany = True
    cur.execute('create table #tmp (unique_id int)')
    # cur.commit()
    print(1)
    cur.executemany('insert into #tmp values (?)', ids)
    # cur.commit()
    print(2)
    cur.execute('create unique index tmp_pk on #tmp (unique_id)')
    # cur.commit()
    print(3)
    cur.execute('select * from #tmp')
    print(4)
    cur.execute('drop table #tmp')

for i in range(1000):
    print('loop {} {}'.format(i, time.time()))
    insert(cxn)
    time.sleep(60)

После многих итераций в ipython:

loop 6 1557992375.617378
1
---------------------------------------------------------------------------
OperationalError                          Traceback (most recent call last)
<ipython-input-1-8ceea4a06017> in <module>
     23 for i in range(1000):
     24         print('loop {} {}'.format(i, time.time()))
---> 25         insert(cxn)
     26         time.sleep(60)

<ipython-input-1-8ceea4a06017> in insert(cxn)
     11         # cur.commit()
     12         print(1)
---> 13         cur.executemany('insert into #tmp values (?)', ids)
     14         # cur.commit()
     15         print(2)

OperationalError: ('08S01', '[08S01] [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.\r\n (10060) (SQLExecute); [08S01] [Microsoft][ODBC Driver 17 for SQL Server]Communication link failure (10060)')

Ошибка:

[08S01] [Microsoft] [Драйвер ODBC 17 для SQL Server] Поставщик TCP:

Попытка подключения не удалась, потому что подключенная сторона не ответила должным образом через некоторое время, или не удалось установить соединение, поскольку подключенный хост не смог ответить.

(10060) (SQLExecute);[08S01] [Microsoft] [Драйвер ODBC 17 для SQL Server] Ошибка канала связи (10060) ')

1 Ответ

0 голосов
/ 16 мая 2019

Это похоже на ошибку клиента, но не ожидайте исправления. Собственный клиент устарел :

Важно

Собственный клиент SQL Server (SQLNCLI) остается устаревшим, и его не рекомендуется использовать для новых разработок.

Microsoft рекомендует ODBC уже довольно давно и прилагает все свои усилия. Это вполне понятно, так как это единственное, что будет работать в Linux.

Сайт документации по SQL Server содержит целый раздел Python с примерами для pyodbc и pymssql . Как они объясняют:

Однако Microsoft прилагает усилия по тестированию и доверяет драйверу pyodbc.

Здесь вы можете найти драйверы ODBC для Windows, MacOS и различных дистрибутивов Linux здесь .

Пример для pyodbc прост и не требует DSN:

import pyodbc 
# Some other example server values are
# server = 'localhost\sqlexpress' # for a named instance
# server = 'myserver,port' # to specify an alternate port
server = 'tcp:myserver.database.windows.net' 
database = 'mydb' 
username = 'myusername' 
password = 'mypassword' 
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
cursor = cnxn.cursor()
...