有人知道为什么我在尝试将dataframe加载到sybase表时出现这个错误吗?[sql炼金术]

2024-09-27 21:23:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图向已经创建的表发送append-a-pandas-dataframe,但一直收到一个错误。在

我正确地连接到服务器。在服务器中,有许多数据库,然后这个表在db_STAFF数据库中。最初,我在做df.to_sql(db_STAFF.dbo.JUNESALES),但我意识到我应该在connString中引用它。我尝试了dbo.JUNESALES以及JUNESALES。下面错误中的表名根据我所称的表(dbo.JUNESALES与{})的不同而改变,但实际的错误保持不变。在

请参阅下面的代码和错误,减去我确实包括的import语句。在

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行上得到这个错误

^{pr2}$

Tags: to服务器数据库urldfdbsql错误
1条回答
网友
1楼 · 发布于 2024-09-27 21:23:54

注意:我是一个SybaseASEDBA;我不使用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))
)

嗯,从哪里开始。。。在

如果将其剪切粘贴到ASE会话中(例如,通过isql命令行工具),您将得到相同的错误:

^{pr2}$

该命令似乎使用了双引号,试图转义非标准标识符。其中一个问题是,默认情况下,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 ...

这里的问题(当然?)就是将owner表包装在一对双引号中;并且尝试使用两种不同的方法来处理非标准标识符并没有帮助。。。双引号。。。方括号;这里的主要问题是双引号告诉ASE方括号实际上是单个标识符[dbo].[JUNESALES]的一部分;还要注意句点(.)也被视为单个标识符的一部分(而不是所有者和表名之间的分隔符)。在

如果试图通过在[dbo][JUNESALES]前后加上双引号来修复his,则会收到以下错误消息:

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 ...

当然,不需要dboJUNESALES周围的分隔符(即,这些是有效的标识符),但是如果您愿意,欢迎使用方括号(例如,作为一种标准编码方法,用于寻址所有分隔符,无论是标准的还是非标准的)。在

注意:以上代码片段是针对ASE15.7(SP138)数据服务器执行的。在

相关问题 更多 >

    热门问题