Извлечение данных из базы данных SQL Server с использованием Python и PYODBC.

avatar
khaledM_dev
1 июля 2021 в 20:19
225
1
0

У меня есть код Python, который подключается к базе данных SQL Server с помощью PYODBC и Streamlit для создания веб-приложения.

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

Если я попытаюсь выполнить SQL-запрос непосредственно к базе данных, он вернет следующий результат:

SELECT        TOP (200) ID, first, last
FROM            t1
WHERE        (first LIKE '%tes%') AND (last LIKE '%tesn%')

где как запрос из python возвращает пусто

sql="select * from testDB.dbo.t1 where ID = ? and first LIKE '%' + ? + '%' and last LIKE '%' + ? + '%' "
param0 = vals[0]
param1=f'{vals[1]}'
param2=f'{vals[2]}'
rows = cursor.execute(sql, param0,param1,param2).fetchall()

Код:

import pandas as pd
import streamlit as st

vals = []
expander_advanced_search = st.beta_expander('Advanced Search')
with expander_advanced_search:
for i, col in enumerate(df.columns):
      val = st_input_update("search for {}".format(col))
      expander_advanced_search.markdown(val, unsafe_allow_html=True)
      vals.append(val)
                                
      if st.form_submit_button("search"):
                            
         if len(vals)>0:
            sql='select * from testDB.dbo.t1 where ID = ? and first LIKE  ? and last LIKE ?  '
            param0 = vals[0]
            param1=f'%{vals[1]}%'
            param2=f'%{vals[2]}%'
            rows = cursor.execute(sql, param0,param1,param2).fetchall()
      df = pd.DataFrame.from_records(rows, columns = [column[0] for column in cursor.description])
      st.dataframe(df)
            

На основе предложения Dale k я использую оператор ИЛИ в запросе выбора:

sql="select * from testDB.dbo.t1 where ID = ? OR first LIKE  ? or last LIKE ? "
param0 = vals[0]   # empty
param1=f'%{vals[1]}%' # nabi
param2=f'%{vals[2]}%' # empty 
rows = cursor.execute(sql, param0,param1,param2).fetchall()

Отображаемый результат:

all the records in the database

Ожидаемый результат:

id first  last
 7 nabil jider
Источник
Dale K
1 июля 2021 в 20:23
0

Когда вы используете такие параметры, что правильно, значения заключаются в кавычки. Вам нужно сделать следующее: first LIKE '%' + ? + '%' и удалить % из переданных значений параметров.

khaledM_dev
1 июля 2021 в 20:27
0

@DaleK о первом комментарии, который я публикую, чтобы сделать мой вопрос более понятным и ясным. а во втором комментарии значения параметров станут param1=f'{vals[1]}'?

khaledM_dev
1 июля 2021 в 20:31
0

@DaleK, я попробовал ваш второй комментарий, он все еще возвращает пустой результат.

Ответы (1)

avatar
dww142
1 июля 2021 в 20:32
0

Я думаю, что это, вероятно, в ваших параметрах - ваша форма отправляет только первые/последние значения, но ваш запрос говорит ID=? Вы не предоставляете идентификатор из формы, поэтому результатов нет. Или он помещает значение из «первого» ввода в vals[0], и результирующий запрос ищет идентификатор = «tes».

Кроме того, загляните в pd.read_sql(), чтобы передать результаты запроса непосредственно в DataFrame/

Выражение OR может быть тем, что вам нужно, если вы хотите, чтобы каждое предложение рассматривалось отдельно:

where ID = ? or first LIKE  ? or last LIKE ?'
khaledM_dev
1 июля 2021 в 20:37
0

я пытаюсь сделать запрос динамическим, когда пользователь вводит ОДИН ИЗ ТРЕБУЕМЫХ ВВОДОВ или вводит их все... и о Or it's putting the value from the 'first' input into vals[0] and the resulting query is looking for an ID = 'tes'. Мой ответ - нет, потому что при отладке он показывает, что vals[0] is the ID vals[1] is the first vals[2] is the last

Dale K
1 июля 2021 в 20:40
0

@khaledM_dev «ОДИН ИЗ НЕОБХОДИМЫХ ВВОДОВ» подразумевает, что вам нужно ИЛИ вместо И . И означает *ВСЕ обязательные входы. Так что на самом деле запрос, который вы используете в коде, не совпадает с запросом, который вы запускали в SSMS.

dww142
1 июля 2021 в 20:41
0

Это более сложное предложение where для учета комбинации трех значений, которые могут присутствовать или отсутствовать. Что ваш отладчик показывает в vals[0], когда вы оставляете ID пустым в форме?

khaledM_dev
1 июля 2021 в 20:45
0

@DaleK, так как написать запрос, чтобы пользователь мог ввести 1 или 2 поля, или если пользователь введет все поля, это сузит его поиск.

Dale K
1 июля 2021 в 20:46
0

@khaledM_dev, как я уже сказал, используйте ИЛИ .

Dale K
1 июля 2021 в 20:47
0

coderhelper.com/questions/333965/…

khaledM_dev
1 июля 2021 в 20:48
0

@dww142 dww142 я попробовал ваш запрос, но он все равно возвращает пустой

khaledM_dev
1 июля 2021 в 20:52
0

@DaleK, если я использую OR, он вернет результат, где бы пользователь ни указал свой параметр поиска.

dww142
1 июля 2021 в 20:52
0

@Dalek может быть прав, попробуйте с OR - это будет оценивать каждый фильтр отдельно, если вы поставите первым, как «% tes%», или последним, как «% tesn%», вы получите «tes tesn», а также «joe». тэсн и тэс кузнец

Dale K
1 июля 2021 в 20:55
1

@khaledM_dev Я думаю, дело в вас, вы сказали, что ваш запрос работает в SSMS, но не в коде. Поэтому мы предположили, что вы знаете, как написать логику, но не умеете обращаться к вызову из кода. Однако кажется, что ваша настоящая проблема в том, что вы не понимаете, как писать логику. Ссылка, которую я разместил несколькими комментариями выше, объясняет это.

khaledM_dev
1 июля 2021 в 21:00
0

@DaleK я отредактирую свой вопрос и покажу результат, если я использую запрос выбора с OR

Dale K
1 июля 2021 в 22:43
0

@khaledM_dev ссылка, которую я дал вам выше, показывает логику как WHERE (@var1 IS NULL OR col1 = @var1) AND (@var2 IS NULL OR col2 = @var2), поэтому вы включаете условие только в том случае, если оно выходит.