简体   繁体   中英

Pandas.read_sql failing with DBAPIError 07002: COUNT field incorrect or syntax error

I am trying to execute a query and return the results to Excel. The query takes in a string of years as input parameters. I am calling it in Python like this:

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)

The query itself, after fixing the end clause, works perfectly when run through SSMS. Just not through the Python code. The error I'm getting is:

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)')

How can I resolve this error?

As @MYGz has already mentioned there is a missing space before order by .

Beside that there is a missing space before group by and the most important one - your CASE ... statement should be "closed" with END .

That said try the following 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'

You can use your SQL pattern directly using .format() - there is no need to overwrite it:

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

You have missed a space in your sql string between year and order by .

Try this:

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 '

Resolved this. A bit of hack, but works. I first changed it to using pyodbc instead of sqlalchemy. so my query string became:

           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()

I then had to add another AND clause with another parameter. For this I created:

    cur_params = (member_list)
    cur_params.append(var_premium)

then passsed cur_params to ind_data.

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

both sets return data correctly now.

Thank you all for reading my post and for all the suggestions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM