Pandas.read_sql失败,DBAPIError 07002:COUNT字段不正确或语法错误

时间:2017-01-04 03:28:13

标签: python sql-server pandas sqlalchemy

我正在尝试执行查询并将结果返回给Excel。查询将输入一串年份作为输入参数。我在Python中用这样的方式调用它:

def flatten(l):
    for el in l:
        try:
            yield from flatten(el)
        except TypeError:
            yield el

my_list = (previous_year_1,previous_year,current_year)
sql = 'select year,sum(sales)/case when sum(t_count)=0 then 1 else sum(t_count) as tx_sales from t_sales where year in ({1})'+ 'group by year' + 'order by year'
sql = sql.format ('?',','.join('?' * len(my_list)))
params = tuple(flatten(member_list))
ind_data = pd.read_sql(sql,engine,params)

在修复end子句之后,查询本身在通过SSMS运行时非常有效。只是不通过Python代码。我得到的错误是:

Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1139, in _execute_context
    context)
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\default.py", line 450, in do_execute
    cursor.execute(statement, parameters)
pyodbc.Error: ('07002', '[07002] [Microsoft][SQL Server Native Client 11.0]COUNT field incorrect or syntax error (0) (SQLExecDirectW)')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "c:\pbp_proj\pbp_proj.py", line 61, in pull_metrics
    ind_data = pd.read_sql_query(sql, engine, params)
  File "C:\Anaconda3\lib\site-packages\pandas\io\sql.py", line 411, in read_sql_query
    parse_dates=parse_dates, chunksize=chunksize)
  File "C:\Anaconda3\lib\site-packages\pandas\io\sql.py", line 1128, in read_query
    result = self.execute(*args)
  File "C:\Anaconda3\lib\site-packages\pandas\io\sql.py", line 1022, in execute
    return self.engine.execute(*args, **kwargs)
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1989, in execute
    return connection.execute(statement, *multiparams, **params)
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 906, in execute
    return self._execute_text(object, multiparams, params)
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1054, in _execute_text
    statement, parameters
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1146, in _execute_context
    context)
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1341, in _handle_dbapi_exception
    exc_info
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 188, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=exc_value)
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 181, in reraise
    raise value.with_traceback(tb)
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1139, in _execute_context
    context)
  File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\default.py", line 450, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.DBAPIError: (pyodbc.Error) ('07002', '[07002] [Microsoft][SQL Server Native Client 11.0]COUNT field incorrect or syntax error (0) (SQLExecDirectW)')

如何解决此错误?

3 个答案:

答案 0 :(得分:3)

正如@MYGz已经提到的那样,order by之前缺少空格。

除了group by之前缺少空格且最重要的空格之外 - CASE ...语句应该与END“关闭”。

那说试试以下SQL:

sql = 'select year,sum(sales)/(case when sum(t_count)=0 then 1 else sum(t_count) end)' \
      +' as tx_sales from t_sales where year in ({1})'+' group by year order by year'

您可以使用.format()直接使用SQL模式 - 无需覆盖它:

params = tuple(flatten(member_list))
ind_data = pd.read_sql(sql.format('?',','.join('?' * len(params))), engine, params)

答案 1 :(得分:2)

您在yearorder by之间错过了sql字符串中的空格。

试试这个:

sql = 'select year,sum(sales)/case when sum(t_count)=0 then 1 else sum(t_count) as tx_sales from t_sales where year in ({1}) '+ 'group by year ' + 'order by year '

答案 2 :(得分:0)

解决了这一点。有点黑客,但有效。我首先将其更改为使用pyodbc而不是sqlalchemy。 所以我的查询字符串变为:

           sql = 'select year,sum(sales)/case when sum(t_count)=0 then 1 else sum(t_count) end as tx_sales from t_sales where year in (?,?,?) '+ ' group by year' + ' order by year'

           ind_data = pd.read_sql(sql, conn, params=member_list)
           summary = ind_data.transpose()

然后我不得不用另一个参数添加另一个AND子句。为此,我创建了:

    cur_params = (member_list)
    cur_params.append(var_premium)

然后将cur_params传递给ind_data。

    ind_data = pd.read_sql(sql, conn, params=cur_params)

现在两者都正确地设置了返回数据。

感谢大家阅读我的帖子和所有建议。