Кто-нибудь знает, почему я получаю эту ошибку при попытке загрузить фрейм данных в таблицу sybase? [sql алхимия]

Я пытаюсь отправить добавление фрейма данных 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 supports Monica 29.07.2018 22:11

Я могу исправить это @ user2357112

WIT 29.07.2018 22:12

Один абзац сейчас @ user2357112

WIT 29.07.2018 22:14

Я почти уверен, что первым аргументом to_sql должно быть просто имя таблицы - без информации о базе данных или схеме и без скобок. (Использует ли ASE даже скобки для экранирования идентификаторов? Я не думаю, что это так.)

user2357112 supports Monica 29.07.2018 22:28
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
1 015
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ПРИМЕЧАНИЕ. Я администратор баз данных 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).

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