Вставка значений в базу данных Access 2003 из приложения Python с использованием pyodbc

В прошлом я много раз проверял stackru и всегда мог найти то, что искал, но мне просто не удается заставить его работать, поэтому я задаю свой первый вопрос.

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

Основная проблема:

У меня есть форма, построенная с использованием Python и tkinter. Когда кнопка в форме нажата, я хочу, чтобы значения были вставлены в базу данных.

Детали:

Я работаю с Python 3.4, pyodbc и базой данных Access 2003.

База данных - это всего лишь 1 таблица с именем file_info, и она имеет следующие поля, поля типа данных указаны за каналом.

ID | AutoNumber

имя файла | Текст

дата | Дата / время

batch_amount | Число

parcel_amount | Число

sum_amount | Число

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

Строка подключения:

db_file = r'''C:\Users\amarquart\Documents\testlockboxdb.mdb'''
user = 'admin'
password = ''
odbc_conn_str = 'DRIVER={Microsoft Access Driver (*.mdb,   
*.accdb)};DBQ=%s;UID=%s;PWD=%s' % \
(db_file, user, password)

conn = pyodbc.connect(odbc_conn_str)
cur = conn.cursor()     

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

def insert_data():
    sql = '''INSERT INTO file_info
    (
      [ID],
      [date],
      [filename],
      [batches_amount],
      [parcels_amount],
      [sum_amount],
    )
    VALUES
    (
      '1',
      'test',
      '8/01/2014 1:00:00 PM',
      '1',
      '1',
      '1',
    );'''

    cur.execute(sql)

    conn.commit()
    cur.commit()
    conn.close()

Это дает эту ошибку:

Исключение в обратном вызове Tkinter (последний последний вызов): файл "C:\Python34\lib\tkinter__init__. Py", строка 1487, в обратном вызове self.func(*args) Файл "C:/Users/amarquart/PycharmProjects/ Тестирование сетки /Source/Grid testing.py", строка 170, запустите файл insert_data() Файл" C: / Users / amarquart / PycharmProjects / Тестирование сетки /Source/Grid testing.py", строка 36, в файле insert_data cur.execute(sql) pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] Синтаксическая ошибка в выражении INSERT INTO. (-3502) (SQLExecDirectW)')

def insert_data():
    sql = ("""INSERT INTO [file_info] ([ID], [date], [filename], [batches_amount],     
         [parcels_amount], [sum_amount])
          VALUES (?, ?, ?, ?, ?, ?)""", [1, '8/01/2014 1:00:00 PM', 'test', 10, 4, 2])
    cur.execute(sql)

    conn.commit()
    cur.commit()
    conn.close()

выдает эту ошибку:

Исключение в обратном вызове Tkinter (последний последний вызов): файл "C:\Python34\lib\tkinter__init__. Py", строка 1487, в обратном вызове self.func(*args) Файл "C:/Users/amarquart/PycharmProjects/ Тестирование сетки /Source/Grid testing.py", строка 154, в прогоне insert_data() Файл" C: / Users / amarquart / PycharmProjects / Тестирование сетки /Source/Grid testing.py", строка 20, в insert_data cur.execute(sql) TypeError: первый аргумент для выполнения должен быть строковым или юникодным запросом.

def insert_data():
    sql = """
    INSERT INTO file_info (ID, date, filename, batches_amount, parcels_amount, sum_amount)
    VALUES (1, '8/01/2014 1:00:00 PM', 'test', 2, 2, 2)
    """ 
    cur.execute(sql)

    conn.commit()
    cur.commit()
    conn.close()    

Дал ту же ошибку, что и последний код

def insert_data():
   cur.execute("INSERT INTO file_info VALUES (AutoNumber, Text, Date/Time, Number,
               Number, Number)",
(1, 'test', '8/01/2014 1:00:00 PM', 2, 2, 2))
   conn.commit()
   cur.commit()
   conn.close()

Дал эту ошибку:

Исключение в обратном вызове Tkinter (последний последний вызов): файл "C:\Python34\lib\tkinter__init__. Py", строка 1487, в обратном вызове self.func(*args) Файл "C:/Users/amarquart/PycharmProjects/ Тестирование сетки /Source/Grid testing.py", строка 153, в прогоне insert_data() Файл" C: / Users / amarquart / PycharmProjects / Тестирование сетки /Source/Grid testing.py", строка 19, в insert_data (1, 'test', ' 01.08.2014 13:00:00 ', 2, 2, 2)) pyodbc.ProgrammingError: ("SQL содержит 0 маркеров параметров, но было предоставлено 6 параметров", "HY000")

Я предполагаю, что все, что я пробовал, крайне неправильно, поэтому любая помощь будет принята с благодарностью.

Спасибо всем.

РЕДАКТИРОВАТЬ:

новые попытки, основанные на первом ответе, единственное отличие состоит в том, что я использую тройные кавычки, потому что код занимает 2 строки

cur.execute("""INSERT INTO file_info (ID, date, filename, batches_amount,   
parcels_amount, sum_amount) 
         VALUES (1, 'test', '8/01/2014 1:00:00 PM', 2, 2, 2)""")
conn.commit()

дает эту ошибку

Исключение в обратном вызове Tkinter (последний последний вызов): файл "C:\Python34\lib\tkinter__init__. Py", строка 1487, в обратном вызове self.func(*args) Файл "C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py", строка 19, в insert_data VALUES (1, 'test', '01.08.2014 13:00:00', 2, 2, 2)''') pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] Синтаксическая ошибка в инструкции INSERT INTO. (-3502) (SQLExecDirectW)')

params = [(1, '8/01/2014 1:00:00 PM', 'test', 2, 2, 2)]
cur.executemany("""insert into file_info(ID, date, filename, batch_amount,   
parcel_amount, sum_amount)
                values (?, ?, ?, ?, ?, ?)""", params)
conn.commit()

дает эту ошибку

Исключение в обратном вызове Tkinter (последний последний вызов): файл "C:\Python34\lib\tkinter__init__. Py", строка 1487, в обратном вызове self.func(*args) Файл "C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py", строка 20, в значениях insert_data (?,?,?,?,?,?)""", Params) pyodbc.Error: ('HYC00', '[HYC00] [Microsoft][ODBC Microsoft Access Driver] Дополнительная функция не реализована (106) (SQLBindParameter)')

2 ответа

Решение

Вы были близки на пару попыток. Date является зарезервированным словом в Access, заключите имя столбца в квадратные скобки и убедитесь, что порядок столбцов соответствует порядку значений:

...
sql = """
INSERT INTO file_info (ID, [date], filename, batches_amount, parcels_amount, sum_amount)
VALUES (1, '8/01/2014 1:00:00 PM', 'test', 2, 2, 2)
""" 
cur.execute(sql)
....

Согласно приведенным ниже комментариям Горда, параметризованные запросы поддерживаются в Access, поэтому идеальным кодом будет:

....
params = (1, '8/01/2014 1:00:00 PM', 'test', 2, 2, 2)
sql = """
INSERT INTO file_info (ID, [date], filename, batches_amount, parcels_amount, sum_amount)
VALUES (?, ?, ?, ?, ?, ?)
""" 
cur.execute(sql, params)
...

У вас немного неправильный порядок: значения должны следовать после определений столбцов и до вставляемых значений, например, в вашем случае:

cur.execute("INSERT INTO file_info (ID, filename, [date], batches_amount, parcels_amount, sum_amount) 
             VALUES (1, 'test', '8/01/2014 1:00:00 PM', 2, 2, 2)")
conn.commit()

Это стандартный синтаксис SQL-вставки, не свойственный pyodbc или Access. Обратите внимание, что вы также можете использовать заполнители (?) Для значений, а затем предоставить массив значений, см. Документацию, в частности, executemany.

Также обратите внимание, что вам нужно только вызвать conn.commit(), а не cur.commit(), смотрите вставку в этих других документах.

РЕДАКТИРОВАТЬ: основываясь на комментариях Beargle, вам нужно поставить дату в [], так как это зарезервированное слово, которое вы использовали в своей первоначальной попытке, но, опять же, вы имели значения даты и имени файла в обратном направлении. Старайтесь избегать использования зарезервированных слов в качестве имен полей в целом, и это относится к другим базам данных, кроме Access.

Другие вопросы по тегам