Pyodb c python чтение незафиксированных данных в хранимой процедуре SQL - PullRequest
0 голосов
/ 17 марта 2020

Я использую Python v 3.7.5 и pyodb c v 4.0.30 (я также тестировал ниже на v 4.0.26, но получил те же результаты). SQL Сервер 2016 с последним SP и CU.

Я вызываю хранимую процедуру с Python, используя Pyodb c. Хранимая процедура выполняет некоторые вставки, затем выбирает вставленные данные для вставки в другую таблицу. Наконец, он запускает оператор SELECT для этой таблицы, чтобы вернуть данные.

Проблема в том, что иногда данные возвращаются, а иногда нет. Это споради c и в нем нет паттерна. Похоже, что pyodb c запускает сохраненный pro c, а затем сразу же запускает SELECT, независимо от того, зафиксированы данные или нет.

Я удалил все операторы with (nolock), добавил BEGIN / END вокруг каждого утверждения et c, чтобы попытаться найти возможное решение, но, похоже, ничего не работает. Мой уровень изоляции по умолчанию READ_COMMITTED. Я даже принудительно настроил его в хранимом профе c, но, конечно, не повезло.

Вот код хранимой процедуры:

    IF @incoming_outgoing = 'incoming'
BEGIN
    --This is the raw audit of the webhook that Twilio calls
    INSERT INTO tbl_django_actions_audit_incoming_whatsapp_message
    VALUES( @sms_message_sid,
            @num_media,
            @sms_sid,
            @sms_status,
            @sms_body,
            @to_number,
            @num_segments,
            @message_sid,
            @account_sid,
            @from_number,
            @api_version,
            @date_time_requested
            )


    DECLARE @count_session INT
    SET @count_session = 0

    DECLARE @hash_to_return varchar(100)
    SET @hash_to_return = @the_hash_for_session


    --Lets check if this conversation has a valid session within the last 24 hours
    --Count should always be 1 or 0. It should never be more than 1
    SELECT @count_session = COUNT(*)
    FROM [dbo].[tbl_django_message_whatsapp_session_main] with (nolock)
    WHERE from_number = @from_number
        AND to_number = @to_number
    AND convert(datetime2, date_time_requested) between dateadd(hour, -24, convert(datetime2,getdate())) AND convert(datetime2, getdate())


    IF @count_session = 0
    BEGIN
        INSERT INTO [dbo].[tbl_django_message_whatsapp_session_main]
        VALUES (
            @from_number,
            @to_number,
            @date_time_requested,
            @hash_to_return
        )

        INSERT INTO [dbo].[tbl_django_message_whatsapp_session_conversation]
        VALUES (
            @hash_to_return,
            @sms_body,
            @incoming_outgoing,
            @date_time_requested
        )


    END
    ELSE
    BEGIN

        --Lets get that session hash. Only 1 record must be returned. ALWAYS. But we add the TOP just in case.
        SELECT TOP 1 @hash_to_return = session_hash
        FROM [dbo].[tbl_django_message_whatsapp_session_main] with (nolock)
        WHERE from_number = @from_number
        AND to_number = @to_number
        AND convert(datetime2, date_time_requested) between dateadd(hour, -24, convert(datetime2,getdate())) AND convert(datetime2, getdate())

        INSERT INTO [dbo].[tbl_django_message_whatsapp_session_conversation]
        VALUES (
            @hash_to_return, --We're using @hash_to_return from above
            @sms_body,
            @incoming_outgoing,
            @date_time_requested
        )
    END

    ---XXXX Here is sometimes returns data, and sometimes not XXXX ----
    SELECT  a.session_hash,
        a.sms_body,
        a.incoming_outgoing
    FROM [dbo].[tbl_django_message_whatsapp_session_conversation] a with (nolock)
    WHERE a.session_hash = @hash_to_return
    --AND a.incoming_outgoing = 'outgoing'
    AND convert(datetime2, a.date_time_requested) between dateadd(hour, -24, convert(datetime2,getdate())) AND convert(datetime2, getdate())
    ORDER BY a.date_time_requested DESC -- The ORDER BY is super important for our logic in Django


END

Мое единственное решение состояло в том, чтобы переместить инструкцию SELECT к другой хранимой процедуре и добавьте time.sleep (2) между хранимым pro c выше и тем, который читает данные. (Я обнаружил, что добавление WAITFOR DELAY до последнего SELECT имеет тот же эффект).

Иногда данные возвращаются, а иногда нет. Это очень споради c без рисунка

...