Вставка значений в базу данных 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.