Запрос отлично работает в SQL Server, но ошибки при попытке прочитать в Pandas DF - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть запрос, который я могу нормально выполнить в SQL Server, но при попытке прочитать его в DF с помощью PYOBC возникают ошибки.

Я скопировал и вставил точный запрос из SQL Server в переменную с именем queryв моем скрипте Python (работает для всех других запросов).

Когда я запускаю запрос в SQL Server, эта часть:

;WITH DeDupe AS (
    -- Trace 105704 was received, returned to vendor, and re-received under same PO. DeDupe handles this
    SELECT DISTINCT A.PurchaseOrderID, A.POLineNumber, D.TraceID
    FROM #UniquePOs A
    LEFT JOIN Trace.ReceivingReport B WITH (NOLOCK)
    ON A.PurchaseOrderID = B.PurchaseOrderID AND A.POLineNumber = B.POLineNumber
    LEFT JOIN Trace.EventInstance C WITH (NOLOCK)
    ON B.EventInstanceID = C.InstanceID AND C.EventID = 'RCVD' -- Keep only receive events, not project transfers to avoid double-counting
    LEFT JOIN Trace.Trace D
    ON C.TraceID = D.TraceID
)
SELECT * INTO #DeDupe FROM DeDupe

SELECT * FROM #DeDupe; <---I take this part out when I try to run the query to get the second table.

;WITH TraceQtys AS (
    -- Use this to solve Case 3 below
    SELECT A.PurchaseOrderID, A.POLineNumber, SUM(B.Quantity) AS 'SumOfTraceQty'
    FROM #DeDupe A
    LEFT JOIN Trace.Trace B
    ON A.TraceID = B.TraceID
    GROUP BY A.PurchaseOrderID, A.POLineNumber
)
SELECT * INTO #TraceQtys FROM TraceQtys

SELECT * FROM #TraceQtys;

Возвращает их как результаты:

PurchaseOrderID                                    POLineNumber TraceID
-------------------------------------------------- ------------ -----------
007004                                             1            NULL
007004                                             1            41963

(2 rows affected)

Warning: Null value is eliminated by an aggregate or other SET operation.

(1 row affected)
PurchaseOrderID                                    POLineNumber SumOfTraceQty
-------------------------------------------------- ------------ ---------------------------------------
007004                                             1            8.00000

Выполнено в моем скрипте Python:

query = 'SET NOCOUNT ON; ' + query
query = query.replace('GO', '')

conn = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};'
                      'Server=SL-SQL;'
                      'Database=TRACE DB;'
                      'Trusted_Connection=yes;')

df = pd.read_sql(query, conn)
df.head()

Вышеприведенное возвращает тот же результат для первой таблицы, но ошибку для второй:

TypeError: объект 'NoneType'не повторяется

Этот похожий запрос работает в Python:

query = '''
SET NOCOUNT ON;
WITH Temp as (
SELECT TraceID, ClassID, SUM(Quantity) as Q
FROM Trace.Trace
GROUP BY TraceID, ClassID
)
SELECT * INTO #Temp FROM Temp
SELECT * FROM #Temp'''

Он также выполняется, если я уберу эту часть в запросе Python:

SUM(B.Quantity) AS 'SumOfTraceQty'

У меня есть похожий фрагмент кода, который успешно работает (далее):

WITH POQtys AS (
    SELECT A.PurchaseOrderID, SUM(B.QtyVouched) AS POTotalQtyVouched
    FROM #orders A
    LEFT JOIN [MSS-ISD-DYN01].App.dbo.PurOrdDet B WITH (NOLOCK)
    ON A.PurchaseOrderID = B.PONbr AND B.InvtID IN ('DIR-MATERIALS', 'ASSET-INVENTORY')
    GROUP BY A.PurchaseOrderID
)
SELECT * INTO #POQtys FROM POQtys

1 Ответ

0 голосов
/ 25 сентября 2019

Для вызовов курсора Python вы обычно можете отправлять только один оператор SQL за раз.Следовательно, почему другие работали, но не ваши вместе, который поддерживает несколько операторов SQL.Однако вы можете использовать несколько CTE в одном вызове, которые даже зависят друг от друга и избегают действий SELECT...INTO.

Ниже также используются более информативные псевдонимы таблиц для исключения привычек ABC и Повсеместно без блокировки привычка.Ниже можно прочитать как одно утверждение в Pandas 'read_sql.

WITH DeDupe AS (
     SELECT DISTINCT u.PurchaseOrderID, u.POLineNumber, t.TraceID 
     FROM #UniquePOs u
     LEFT JOIN Trace.ReceivingReport r 
          ON u.PurchaseOrderID = r.PurchaseOrderID
          AND u.POLineNumber = r.POLineNumber 
     LEFT JOIN Trace.EventInstance e
          ON r.EventInstanceID = e.InstanceID 
          AND e.EventID = 'RCVD' 
     LEFT JOIN Trace.Trace t
          ON e.TraceID = t.TraceID 
), 
TraceQtys AS (
     SELECT d.PurchaseOrderID, d.POLineNumber, SUM(t.Quantity) AS 'SumOfTraceQty' 
     FROM DeDupe d
     LEFT JOIN Trace.Trace t
          ON d.TraceID = t.TraceID 
     GROUP BY d.PurchaseOrderID, t.POLineNumber
) 

SELECT * FROM TraceQtys
...