我正在尝试向已创建的表发送追加熊猫数据帧,但我不断收到错误消息。
我已正确连接到服务器。在服务器内,有许多数据库,然后此表在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 :(得分:4)
注意:我是Sybase ASE DBA;我不使用python / pandas / sqlalchemy / etc;因此,虽然我可以告诉您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))
)
嗯,从哪里开始...
如果要将其剪切-n-粘贴到ASE会话中(例如,通过isql
命令行工具),则会收到相同的错误:
Msg 102, Level 15, State 181:
Server 'ASE200', Line 2:
Incorrect syntax near '('.
该命令似乎正在使用双引号来尝试转义非标准标识符。这样做的一个问题是,默认情况下,ASE不会将双引号识别为非标准标识符的转义字符。要解决此问题,您需要启用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)数据服务器执行的。