#sql #sql-server #pyodbc
#sql #sql-сервер #pyodbc
Вопрос:
for fileName in fileNames:
with open(fileName, mode="rt", encoding="utf-8", newline="") as csvfile:
csvFile = csv.reader(csvfile, delimiter=',')
header = next(csvFile)
headers = map((lambda x: x.strip()), header)
insert = 'INSERT INTO TEST ('.format(tableChoice) ', '.join(headers) ') VALUES '
for row , record in enumerate(csvFile, start=1):
values = map((lambda x: "'" x.strip() "'"), record)
myCursor.execute(insert '(' ', '.join(values) ');' )
cnxn.commit()
Я получаю приведенную ниже ошибку, когда дохожу до execute
строки в скрипте. Мне просто нужны данные, извлеченные из csv, для вставки в базу данных, строка за строкой. Кто-нибудь знает, что вызывает ошибку?
Ошибка программирования: (‘42000’, «[42000] [ Microsoft] [Драйвер ODBC SQL Server] [SQL Server] Неправильный синтаксис рядом с ‘-‘. (102) (SQLExecDirectW)»)
Редактировать:
Строка запроса SQL выглядит следующим образом:
INSERT INTO TEST (this, that, those) VALUES ('1', '11', '111');
INSERT INTO TEST (this, that, those) VALUES ('2', '22', '222');
INSERT INTO TEST (this, that, those) VALUES ('3', '33', '333');
Комментарии:
1. Покажите нам окончательный SQL, поскольку он передается на сервер.
2. Отредактированное исходное сообщение
3. Похоже, вы должны разделять имена столбцов, если в них есть дефисы (
-
). Или, что еще лучше, измените имена ваших объектов, чтобы их не нужно было определять разделителями в первую очередь.4. При создании списка имен столбцов вы должны использовать
", ".join([f"[{x}]" for x in headers])
5. Кроме того, вам действительно следует параметризовать свой запрос, и если ваши CSV-файлы содержат более нескольких десятков строк, вы также должны использовать
myCursor.fast_executemany = True
Ответ №1:
Вероятно, проблема связана со специальными символами в именах столбцов, например, -
которые требуют заключения в квадратные скобки для экранирования в SQL Server. Кроме того, рассмотрите возможность использования согласованного форматирования строк в Python и csv.DictReader
создания параметризованного запроса, за которым следует executemany
для вставки:
for fileName in fileNames:
with open(fileName, mode="rt", encoding="utf-8", newline="") as csvfile:
reader = csv.DictReader(f)
data = [row for row in reader]
# BUILD SQL WITH [...] ESCAPED COLUMNS AND ? PARAM PLACEHOLDERS
sql = "INSERT INTO [Test] ([{cols}]) VALUES ({prms})"
sql = sql.format(cols="], [".join(map(lambda x: x.strip(), data[0].keys())),
prms=", ".join(['?'] * len(data[0])))
# APPEND ALL ROWS AND BIND PARAMS
myCursor.executemany(sql, [list(d.values()) for d in data])
cnxn.commit()