Я пытаюсь отправить добавление фрейма данных pandas в уже созданную таблицу, но все время получаю сообщение об ошибке.
Я правильно подключился к серверу. На сервере есть много баз данных, и эта таблица находится в базе данных db_STAFF
. Изначально я делал df.to_sql(db_STAFF.dbo.JUNESALES)
, но понял, что должен ссылаться на это в connString. Я пробовал dbo.JUNESALES
, а также просто JUNESALES
. Имя таблицы в приведенной ниже ошибке изменяется в зависимости от того, что я называю таблицей (dbo.JUNESALES
по сравнению с JUNESALES
), но фактическая ошибка остается той же.
См. Код и ошибку ниже, за вычетом операторов импорта, которые я включил.
df = pd.DataFrame(lists_data)
connString = "DRIVER = {Adaptive Server Enterprise};SERVER=XXXX,DATABASE = 'db_STAFF'...."
conn_url = quote_plus(connString)
new_connection = "sybase+pyodbc:///?odbc_connect = {}".format(conn_url)
engine = create_engine(new_connection)
df.to_sql('[dbo].[JUNESALES]', con=engine, if_exists = 'append', index = False) #I also tried this without the brackets, I read that with brackets it worked for someone
engine.execute("SELECT * FROM dbo.JUNESALES ").fetchall()
cursor.execute(statement, parameters)
Я получаю эту ошибку в строке df.to_sql
sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) ('42000', "[42000] [Sybase][ODBC Driver][Adaptive Server Enterprise] Incorrect syntax near '('.\n (102) (SQLExecDirectW)") [SQL: '\nCREATE TABLE "[dbo].[JUNESALES]" (\n\t"0" BIGINT NULL, \n\t"1" BIGINT NULL, \n\t"2" FLOAT NULL, \n\t"3" TEXT NULL, \n\t"4" BIT NULL, \n\t"5" BIT NULL, \n\t"6" FLOAT NULL, \n\t"7" FLOAT NULL, \n\t"8" FLOAT NULL, \n\t"9" FLOAT NULL, \n\t"10" FLOAT NULL, \n\t"11" BIGINT NULL, \n\tCHECK ("4" IN (0, 1)), \n\tCHECK ("5" IN (0, 1))\n)\n\n'] (Background on this error at: http://sqlalche.me/e/f405)
Я могу исправить это @ user2357112
Один абзац сейчас @ user2357112
Я почти уверен, что первым аргументом to_sql
должно быть просто имя таблицы - без информации о базе данных или схеме и без скобок. (Использует ли ASE даже скобки для экранирования идентификаторов? Я не думаю, что это так.)
ПРИМЕЧАНИЕ. Я администратор баз данных Sybase ASE; Я не работаю с python / pandas / sqlalchemy / и т. Д .; Итак, пока я могу рассказать вам, почему ASE генерирует ошибку, и даже показать вам один способ правильно отформатировать команду create table
... Я понятия не имею, как сообщить вашему приложению, как (пере) кодировать команду create table
(при условии, что это то, над чем вы не имеете прямого контроля).
Сообщение об ошибке сообщает нам, что команда create table
выглядит следующим образом:
CREATE TABLE "[dbo].[JUNESALES]" (
"0" BIGINT NULL,
"1" BIGINT NULL,
"2" FLOAT NULL,
"3" TEXT NULL,
"4" BIT NULL,
"5" BIT NULL,
"6" FLOAT NULL,
"7" FLOAT NULL,
"8" FLOAT NULL,
"9" FLOAT NULL,
"10" FLOAT NULL,
"11" BIGINT NULL,
CHECK ("4" IN (0, 1)),
CHECK ("5" IN (0, 1))
)
Хмммм, с чего начать ...
Если бы вам пришлось вырезать-и-вставить это в сеанс ASE (например, с помощью инструмента командной строки isql
), вы получите ту же ошибку:
Msg 102, Level 15, State 181:
Server 'ASE200', Line 2:
Incorrect syntax near '('.
Команда использует двойные кавычки, пытаясь избежать нестандартных идентификаторов. Одна из проблем заключается в том, что по умолчанию ASE не распознает двойные кавычки как escape-символ для нестандартных идентификаторов. Чтобы обойти это, вам нужно включить quoted_identifier
, например:
set quoted_identifier on
CREATE TABLE ...
... snip ...
set quoted_identifier off -- or leave 'on' if you're going to continue using double quotes to designate non-standard identifiers
go
Хотя это поможет вам преодолеть ошибку Msg 102
(синтаксис), теперь вы видите несколько новых ошибок:
Msg 2718, Level 16, State 1:
Server 'ASE200', Line 2:
Column or parameter #5: -- can't specify Null values on a column of type BIT.
Msg 2718, Level 16, State 1:
Server 'ASE200', Line 2:
Column or parameter #6: -- can't specify Null values on a column of type BIT.
Чтобы исправить эти ошибки, вам нужно либо обозначить столбцы BIT
как NOT NULL
, либо изменить тип данных на что-то другое, кроме BIT
(например, tinyint
?), Хотя теперь вам может потребоваться добавить код приложения или ограничения check
, чтобы ограничить допустимые значения до 0 / 1 ... ??):
set quoted_identifier on
CREATE TABLE ...
... snip ...
"4" BIT not NULL,
"5" BIT not NULL,
... snip ...
set quoted_identifier off
go
На этом этапе таблица должна быть создана (то есть без ошибок), но ... вы еще не из леса.
Если вы запустите sp_help
, вы увидите свою таблицу в следующем виде:
sp_help
go
Name Owner Object_type
--------------------------- ----- ------------
... snip ...
[dbo].[JUNESALES] dbo user table
... snip ...
Проблема здесь (конечно?) В том, что вы заключили таблицу владельца а также в одну пару двойных кавычек; и то, что вы пытаетесь использовать 2 разных метода для обработки нестандартных идентификаторов, не помогает ... двойные кавычки ... квадратные скобки; главная проблема здесь в том, что двойные кавычки говорят ASE, что квадратные скобки на самом деле являются частью единственного идентификатора, называемого [dbo].[JUNESALES]
; также обратите внимание, что точка (.
) также считается частью единого идентификатора (в отличие от разделителя между владельцем и именами таблиц).
Если вы попытаетесь исправить это, заключив в двойные кавычки [dbo]
и [JUNESALES]
, вы получите следующее сообщение об ошибке:
set quoted_identifier on
CREATE TABLE "[dbo]"."[JUNESALES]"
... snip ...
go
Msg 2734, Level 16, State 1:
Server 'ASE200', Line 2:
User name [dbo] does not exist in sysusers.
!!! notice the square brackets are considered as part of the user name !!!
Хорошо, мы можем обойти это, удалив квадратные скобки из [dbo]
, но если вы не сделаете то же самое для имени таблицы ... команда create table
завершится успешно, но скобки станут частью имени таблицы (в отличие от использования разделители), например:
set quoted_identifier on
CREATE TABLE "dbo"."[JUNESALES]"
... snip ...
go
sp_help
go
Name Owner Object_type
--------------------------- ----- ------------
... snip ...
[JUNESALES] dbo user table
... snip ...
ASE поддерживает использование двойных кавычек в качестве разделителя для нестандартных идентификаторов ... если вы сначала выдаете set quoted_identifier on
.
ASE также поддерживает использование квадратных скобок в качестве разделителя для нестандартных идентификаторов ... а также нет необходимости вводить команду set quoted_identier on
.
Я предлагаю вам выяснить, как использовать только один метод разграничения нестандартных идентификаторов (квадратные скобки немного чище, не требуют выдачи set quoted_identifier on
и позволяют использовать двойные кавычки для разграничения текстовых / символьных данных).
set quoted_identifier off -- optional if already set to 'off'
CREATE TABLE [dbo].[JUNESALES] (
[0] BIGINT NULL,
[1] BIGINT NULL,
[2] FLOAT NULL,
[3] TEXT NULL,
[4] BIT not NULL,
[5] BIT not NULL,
[6] FLOAT NULL,
[7] FLOAT NULL,
[8] FLOAT NULL,
[9] FLOAT NULL,
[10] FLOAT NULL,
[11] BIGINT NULL,
CHECK ([4] IN (0, 1)),
CHECK ([5] IN (0, 1))
)
go
sp_help
go
Name Owner Object_type
--------------------------- ----- ------------
... snip ...
JUNESALES dbo user table
... snip ...
Конечно, разделители вокруг dbo
и JUNESALES
не нужны (т. Е. Это действительные идентификаторы), но вы можете использовать квадратные скобки, если хотите (например, в качестве стандартного метода кодирования для адресации всех разделителей, стандартных или стандартных). нестандартные).
ПРИМЕЧАНИЕ. Приведенные выше фрагменты кода были выполнены на сервере данных ASE 15.7 (SP138).
«ошибка в одном абзаце, я просто разделил строки для облегчения чтения» - пожалуйста, не делайте этого. Часто очень важно точное форматирование сообщений об ошибках, вплоть до отдельных пробелов.