Синтаксическая ошибка при вставке в файл MDB 2003 с помощью Pyodbc - PullRequest
0 голосов
/ 01 февраля 2019

Я пытаюсь написать 2003 MDB файлы с нуля.У меня уже есть файл с именами таблиц и столбцов (у меня 112 столбцов).В моей попытке я читаю строки из DataFrame pandas (именованные разделы в моем коде) и добавляю эти строки в файл mdb.Но при использовании синтаксиса pyodbc INSERT INTO он выдает мне эту ошибку:

ProgrammingError: ('42000', '[42000] [Microsoft] [Драйвер ODBC Microsoft Access] Ошибка синтаксиса выражения' Экваториально-TB-BG-CA_IRI-1.0_SNP-1.0_ACA-0_ESAL-1000 '. (-3100) (SQLExecDirectW) ")

вот мой код:

for k in range(len(sections)):
    cols = tuple(list(sections.columns))
    vals = tuple(list(sections.iloc[k]))
    action = 'INSERT INTO SECTIONS {columns} VALUES {values}'.format(columns = str(cols).replace("'",""), values = str(vals).replace("'",""))
    cursor.execute(action)
    conn.commit()

Кто-нибудь знает, почему у меня такая проблема?

1 Ответ

0 голосов
/ 01 февраля 2019

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

Чтобы продемонстрировать проблему, см. Заполнение неизвестных значений ниже.Обратите внимание, что строковые элементы, переданные в VALUES, не заключены в кавычки:

sections_columns = ['database', 'tool']
cols = tuple(list(sections_columns))

sections_vals = ['ms-access', 'pandas']
vals = tuple(list(sections_vals))

action = 'INSERT INTO SECTIONS {columns} VALUES {values}'.\
          format(columns = str(cols).replace("'",""), values = str(vals).replace("'",""))

print(action)
# INSERT INTO SECTIONS (database, tool) VALUES (ms-access, pandas)

Теперь вы можете оставить в одинарных кавычках, которые вы заменяете в str(vals):

action = 'INSERT INTO SECTIONS {columns} VALUES {values}'.\
          format(columns = str(cols).replace("'",""), values = str(vals))

print(action)
# INSERT INTO SECTIONS (database, tool) VALUES ('ms-access', 'pandas')

Но, что еще лучше, рассмотрите возможность параметризации запроса с помощью заполнителей qmark и передачи значений в качестве параметров (второй аргумент cursor.execute(query, params)).Это избавляет от необходимости заключать в кавычки или заключать в кавычки строковые или числовые значения:

# MOVED OUTSIDE LOOP AS UNCHANGING OBJECTS
cols = tuple(sections.columns)            # REMOVED UNNEEDED list()
qmarks = tuple(['?' for i in cols])       # NEW OBJECT

action = 'INSERT INTO SECTIONS {columns} VALUES {qmarks}'.\
          format(columns = str(cols).replace("'",""), qmarks = str(qmarks))
# INSERT INTO SECTIONS (col1, col2, col3, ...) VALUES (?, ?, ?...)

for k in range(len(sections)):        
    vals = list(sections.iloc[k])         # REMOVED tuple()

    cursor.execute(action, vals)          # EXECUTE PARAMETERIZED QUERY
    conn.commit()

Еще лучше избегать циклических операций с executemany из DataFrame.values.tolist() с использованием подготовленного оператора:

# PREPARED STATEMENT
cols = tuple(sections.columns)
qmarks = tuple(['?' for i in cols])

action = 'INSERT INTO SECTIONS {columns} VALUES {qmarks}'.\
          format(columns = str(cols).replace("'",""), qmarks = str(qmarks))

# EXECUTE PARAMETERIZED QUERY
cursor.executemany(action, sections.values.tolist())   
conn.commit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...