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

1

Я пытаюсь отправить добавление фрейма данных 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)
  • 0
    «ошибка в одном абзаце, я просто разделил строки для удобства чтения» - пожалуйста, не делайте этого. Точное форматирование сообщения об ошибке часто очень важно, даже до отдельных пробелов .
  • 0
    Я могу это исправить @ user2357112
Показать ещё 2 комментария
Теги:
pandas
sqlalchemy
database-connection
sybase-ase

1 ответ

3
Лучший ответ

ПРИМЕЧАНИЕ. Я - администратор базы данных Sybase ASE; Я не работаю с python/pandas/sqlalchemy/etc; поэтому пока я могу сказать вам, почему ASE создает ошибку и даже показывает вам один способ правильно форматировать команду create table... Я понятия не имею, как говорить о том, как приложение (re) кодирует команду 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 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 не нужны (т. JUNESALES Это действительные идентификаторы), но вы можете использовать квадратные скобки, если хотите (например, в качестве стандартного метода кодирования для адресации всех разделителей, будь то стандартные или нестандартные).

ПРИМЕЧАНИЕ. Над фрагментами кода были выполнены каскадные данные для ASA 15.7 (SP138).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню