Циклическое выполнение Python для получения различных кадров данных из базы данных SQL

#python #pandas #loops #pyodbc

Вопрос:

Я пытаюсь подключиться к базе данных SQL и в цикле создать отдельные фреймы данных для каждого отдельного экземпляра идентификатора, содержащие все данные, связанные с этим идентификатором. Я пробовал несколько способов, но до сих пор безуспешно. Я довольно новичок во всем этом, так что, вероятно, совершаю некоторые ошибки новичка.

Попытка 1:

 import pandas as pd
import pyodbc

conn = pyodbc.connect('Driver={SQL Server};'
                      'Server=Server_name;'
                      'Database=Database;'
                      'UID=Username;'
                      'PWD=password;'
                      'Trusted_Connection=yes;')

Name = ['HR','ZA','PR','FW']

for x in Name:
    
    SQL = '''
        SELECT *
        FROM Database
        WHERE Id = {x}'''.format(x = x)
    cursor = conn.cursor()
    cursor.execute(SQL)
    df = pd.read_sql_query(SQL)
 

В этом коде я получаю ошибку программирования «недопустимое имя столбца» при первом имени «HL».

Попытка 2:

 import pandas as pd
import pyodbc

conn = pyodbc.connect('Driver={SQL Server};'
                      'Server=Server_name;'
                      'Database=Database;'
                      'UID=Username;'
                      'PWD=password;'
                      'Trusted_Connection=yes;')

    SQL = '''
        SELECT *
        FROM Database
    
conn.autocommit = True

cursor.execute(SQL)

for [Id] in cursor:
    df = pd.Dataframe(SQL,conn)
        
 

В этом коде я получаю «Ошибка значения: слишком много значений для распаковки (ожидается 1)» — в операторе for.

Я хочу добавить гораздо больше кода в цикл for, поэтому мне нужно настроить его для работы с каждым идентификатором. Я надеюсь, что в этом есть смысл. Любые рекомендации будут весьма признательны. Спасибо

Обновить:

Спасибо за все комментарии/ответы. По какой-то причине я просто не мог заставить его работать ни в одном из вышеперечисленных форматов, поэтому я вернулся к тому, с чего начал, теперь я понимаю, как включить синтаксис переменной цикла. Теперь работает следующее:

 import pandas as pd
import pyodbc

conn = pyodbc.connect('Driver={SQL Server};'
                          'Server=Server_name;'
                          'Database=Database;'
                          'UID=Username;'
                          'PWD=password;'
                          'Trusted_Connection=yes;')
    
Name = ['HR','ZA','PR','FW']

for x in Name:

    SQL = pd.read_sql_query(
    '''
    SELECT *
    FROM Database_table
    WHERE Id = '{x}'
    '''.format(x = x), conn)

    df = pd.DataFrame(SQL)
    
 

Комментарии:

1. Помогает ли изменение WHERE Id = {x} WHERE Id = '{x}' решить эту проблему для вас в попытке 1?

2. Кроме того, я бы предложил использовать sqlalchemy в качестве интерфейса для вашей БД, он хорошо поддерживается и будет полезен вам, если ваши взаимодействия с БД станут более сложными

3. Спасибо @YaakovBressler — если я сделаю это, я получу другое сообщение об ошибке — ошибка типа: read_sql_query() отсутствует 1 требуемый позиционный аргумент: «con»

4. Это странно. Единственное, что вы изменили, — это форматирование строк?

5. Спасибо за ваше руководство — теперь у меня все работает — см. Выше

Ответ №1:

Я думаю, что если вы попробуете вариант с вашей первой попытки, например:

 for x in Name:

    SQL = '''
          SELECT *
          FROM Database
          WHERE Id = ?'''
    cursor = conn.cursor()
    cursor.execute(SQL)
    df = pd.read_sql_query(SQL, params={x})
 

Вероятно, это должно сработать 🙂

Комментарии:

1. Спасибо. Если я изменю это, я получу следующее сообщение (которое, вероятно, является отдельной проблемой?) — Ошибка: (‘07002’, ‘[07002] [Microsoft][Драйвер ODBC SQL Server]Неверное поле подсчета или синтаксическая ошибка (0) (SQLExecDirectW)’)

2. Хм, интересно. Является ли база данных именем базы данных или таблицы базы данных?

3. База данных, на которую ссылается Conn, является именем базы данных, но база данных, на которую ссылается SQL, является таблицей базы данных. Я должен был сделать это более ясным в своем обобщенном коде, извините. Спасибо за всю вашу помощь и руководство. Как вы можете видеть выше, у меня это работает — спасибо

4. Рад слышать 🙂