У меня есть программа на python, которая каждые 10 минут запрашивает обновленную таблицу LIVE, хранящуюся в SQL Server.При первом выполнении возвращает правильные результаты.В конце концов запрос начинает возвращать пустые результаты, даже если таблица фактически содержит новые данные.Я заметил, что через несколько часов запрос действительно вытягивает данные.Я хочу знать, почему запрос не получил результаты, когда они фактически были доступны в таблице?
ИСПОЛЬЗОВАННЫЕ ИНСТРУМЕНТЫ
Моя программа на Python написана на Python3 с использованиемБиблиотека pyodbc для подключения к УДАЛЕННОМУ SQL Server 12, где хранится представление.Представление выбирает данные из таблиц, которые постоянно обновляются.Моя программа разбита на несколько файлов.Один модуль этой программы порождает процесс потока, который генерирует строку запроса SQL, содержащую две переменные.Одна из переменных вычисляется до инициации потока, а вторая переменная является значением, которое постоянно изменяет запрос SQL.
IDEA
Идея состоит в том, чтобы продолжать тянутьномера событий из таблиц (новые номера событий добавляются постоянно).Поэтому поток продолжает выполнять запрос каждые 10 минут, чтобы проверить наличие новых номеров событий.В запросе SQL содержится условие WHERE, в котором говорится, чтобы получить число событий> last_pulled_event_number.Этот "last_pulled_event_number" рассчитывается на основе результатов, возвращаемых запросом.Если он возвращает пустые результаты, переменная содержит свое последнее значение.
ПРОБЛЕМА
Поскольку представление в SQL Server не будет обновляться каждую минуту, ожидается, чтоиногда при выполнении запроса новые данные добавляться не будут, поэтому результаты будут пустыми.При первом выполнении запрос возвращает правильные результаты.Поскольку цикл продолжается, вторая и третья попытки, как ожидается, не дадут результатов, но через 30 минут в таблицу будет добавлена как минимум одна новая строка, которую может видеть представление.Но когда мой запрос выполняется через 30 минут, он получает пустые результаты.
Вещи, которые я пробовал
Я точно знаю, что таблица и представление содержат данныепотому что я проверил это двумя разными способами.Моя программа работала в течение 6 часов, а последнему извлеченному событию было 3 часа.Я открыл SQL Server Studio и запустил точно такой же запрос с теми же учетными данными, и он получил новые результаты.Затем, чтобы убедиться, что SQL Server Studio ничего не делает, я скопировал код и запустил программу на python с тем же кодом и тем же запросом.На этот раз программа также дала мне ожидаемые результаты.Пока я тестировал эти два метода, моя программа, которая работала в течение 6 часов, завершила свой интервал, а затем снова запустила запрос.Программа, однако, получила пустые результаты, которые не имеют смысла.
Также, когда я остановил программу и перезапустил ее.Запрос ведет себя как ожидалось и получает новые результаты.
Я использую библиотеку журналов в python для отладки.Я заметил, что программа в конечном итоге получает новые результаты, но получает их с большой задержкой.Что меня смущает, так это то, что программа не может видеть данные, когда другие скрипты или программы, которые запускаются свежими, могут видеть их.Это потому, что программа работала в течение 6 или более часов, вызывая это?Может ли быть так, что, поскольку один и тот же запрос выполняется несколько раз, кэшированные результаты возвращаются мне?Почему система не знает, что результаты кэша больше не действительны?
Любая помощь по этому вопросу приветствуется!
# My code in the thread
while not self.shutdown_flag.is_set():
# SQL Query that pulls incident
sql_query = '''
select varc.EventNumber
from vw_Events varc (nolock)
where varc.CompanyNumber in (
''' + string_of_cust_numbers + '''
)
and varc.bCommented = 0
and varc.EventNumber > ''' + str(last_known_inc_number) + '''
and varc.InsertTimeStampGMT >= GETDATE() - 1 -- Need to look at the Added to Queue value rather than when the incident was generated
order by varc.EventNumber
'''
exec_msg = 'Querying the SQL Server database to fetch event numbers from live queue'
exception_msg = 'Queue Fetching Query Execution Failed!'
query_results = self.db_util.executeASQL(sql_cursor, sql_query, 'INFO', exec_msg, exception_msg)
if query_results is None:
logging.critical('Queue Fetcher query had some issue. Investigate. Terminating program')
return
else:
logging.info('Fetched Queue: {}'.format(query_results))
# Check if the query returned any results and then add to queue
if query_results:
for row in query_results:
my_queue.put(
int(row[0])) # Adds the first element which is going to be the incident number in the queue one by one
# TODO Need to add Queue size checks over here
# Update last incident number which will be used to fetch only the new incident numbers next time
if query_results: # This checks if the results list is empty
last_known_inc_number = query_results.pop()[0] # Last entry in results, First element in the tuple
# Constant Time Interval Gap - 1 minutes for now
logging.debug('Last Known Inc Number: {}'.format(last_known_inc_number))
logging.info('Sleeping for 10 minutes')
time.sleep(600)
# Custom SQL execute function defined in other file
def executeASQL(self, db_cursor, sql_query, loglevel, exec_msg, exception_msg):
'''
This function is a wrapper around ASQL execute query to make the code more readable
:param db_cursor: SQL Cursor object
:param sql_query: String - sql query to execute
:param loglevel: String - Logging level for execution message
:param exec_msg: String - Logging message during execution
:param exception_msg: String - Logging message if an exception arises
:return: Query results if succeeded else None
'''
try:
self.loglevel_dict.get(loglevel, 'DEBUG')(exec_msg)
db_cursor.execute(sql_query)
results = db_cursor.fetchall()
return results
except pyodbc.Error as err:
self.loglevel_dict.get(loglevel, 'EXCEPTION')(exception_msg)
# logging.exception('Execution of ASQL Query to determine SIP failed')
return None
Фактические результаты Выбранный журнал очередиговорит пустой список -> [] Даже когда представление имеет данные, потому что когда мы выполняем тот же запрос с помощью другой программы на Python, оно возвращает результаты
Ожидаемые результаты Выбранный журнал очередидолжен получить новые данные -> [1,2,3]