我正在使用SQLAchemy和python来动态运行SQL查询。但是它给出了错误。
这是我运行查询的命令:
data = engine.execute(m_query, week=Cohort_week, metric=metric, p1=val1, p2=val2).fetchall()
这里Cohort_week,val1,val2是整数,metric是一个字符串。
这是我的SQL查询:
select cus.week,pdp_views, id, :metric,
case
when :metric <= :p2 then 3
when :metric > :p2 and :metric < :p1 then 2
when :metric >= :p1 then 1
end as HML
from
dev.master_abtest_customers cus
where cus.week= :week
错误是:
DataError Traceback (most recent call last)
<ipython-input-25-30f7e92cbea3> in <module>()
12 m_query = text(m_query)
13
---> 14 data = engine.execute(m_query, week=week, metric=metric, p1=val1, p2=val2).fetchall()
15
16 data = pd.DataFrame(data)
C:\Users\MI0185\AppData\Local\Enthought\Canopy\User\lib\site-packages\sqlalchemy-1.1.0b1-py2.7-win-amd64.egg\sqlalchemy\engine\base.pyc in execute(self, statement, *multiparams, **params)
2050
2051 connection = self.contextual_connect(close_with_result=True)
-> 2052 return connection.execute(statement, *multiparams, **params)
2053
2054 def scalar(self, statement, *multiparams, **params):
C:\Users\MI0185\AppData\Local\Enthought\Canopy\User\lib\site-packages\sqlalchemy-1.1.0b1-py2.7-win-amd64.egg\sqlalchemy\engine\base.pyc in execute(self, object, *multiparams, **params)
945 type(object))
946 else:
--> 947 return meth(self, multiparams, params)
948
949 def _execute_function(self, func, multiparams, params):
C:\Users\MI0185\AppData\Local\Enthought\Canopy\User\lib\site-packages\sqlalchemy-1.1.0b1-py2.7-win-amd64.egg\sqlalchemy\sql\elements.pyc in _execute_on_connection(self, connection, multiparams, params)
260
261 def _execute_on_connection(self, connection, multiparams, params):
--> 262 return connection._execute_clauseelement(self, multiparams, params)
263
264 def unique_params(self, *optionaldict, **kwargs):
C:\Users\MI0185\AppData\Local\Enthought\Canopy\User\lib\site-packages\sqlalchemy-1.1.0b1-py2.7-win-amd64.egg\sqlalchemy\engine\base.pyc in _execute_clauseelement(self, elem, multiparams, params)
1053 compiled_sql,
1054 distilled_params,
-> 1055 compiled_sql, distilled_params
1056 )
1057 if self._has_events or self.engine._has_events:
C:\Users\MI0185\AppData\Local\Enthought\Canopy\User\lib\site-packages\sqlalchemy-1.1.0b1-py2.7-win-amd64.egg\sqlalchemy\engine\base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
1189 parameters,
1190 cursor,
-> 1191 context)
1192
1193 if self._has_events or self.engine._has_events:
C:\Users\MI0185\AppData\Local\Enthought\Canopy\User\lib\site-packages\sqlalchemy-1.1.0b1-py2.7-win-amd64.egg\sqlalchemy\engine\base.pyc in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
1384 util.raise_from_cause(
1385 sqlalchemy_exception,
-> 1386 exc_info
1387 )
1388 else:
C:\Users\MI0185\AppData\Local\Enthought\Canopy\User\lib\site-packages\sqlalchemy-1.1.0b1-py2.7-win-amd64.egg\sqlalchemy\util\compat.pyc in raise_from_cause(exception, exc_info)
200 exc_type, exc_value, exc_tb = exc_info
201 cause = exc_value if exc_value is not exception else None
--> 202 reraise(type(exception), exception, tb=exc_tb, cause=cause)
203
204 if py3k:
C:\Users\MI0185\AppData\Local\Enthought\Canopy\User\lib\site-packages\sqlalchemy-1.1.0b1-py2.7-win-amd64.egg\sqlalchemy\engine\base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
1182 statement,
1183 parameters,
-> 1184 context)
1185 except Exception as e:
1186 self._handle_dbapi_exception(
C:\Users\MI0185\AppData\Local\Enthought\Canopy\User\lib\site-packages\sqlalchemy-1.1.0b1-py2.7-win-amd64.egg\sqlalchemy\engine\default.pyc in do_execute(self, cursor, statement, parameters, context)
460
461 def do_execute(self, cursor, statement, parameters, context=None):
--> 462 cursor.execute(statement, parameters)
463
464 def do_execute_no_params(self, cursor, statement, context=None):
DataError: (psycopg2.DataError) invalid input syntax for integer: "pdp_views"
[SQL: 'select cus.week, id, %(metric)s,\n case\n when %(metric)s <= %(p2)s then 3\n when %(metric)s > %(p2)s and %(metric)s < %(p1)s then 2 \n when %(metric)s >= %(p1)s then 1\n end as HML\n from \n dev.master_abtest_customers cus\n where cus.week= %(week)s\n\t\t\n\t\t'] [parameters: {'p2': 20L, 'week': 22L, 'metric': u'pdp_views', 'p1': 40L}]
我尝试过将类型转换为val1,val2和week作为int(即使用int(val1)等)。但仍然是同样的错误。
你能帮我解决这个问题吗?
答案 0 :(得分:0)
您希望将pdp_views
列中的值与p1
和p2
进行比较,但您实际所做的是比较字符串'pdp_views'
使用p1
和p2
,它们具有不兼容的类型。
您应该动态构建查询:
def get_m_query(week, metric, p1, p2):
cus = master_abtest_customers.alias("cus")
metric = getattr(cus.c, metric)
return select([
cus.c.week,
cus.c.pdp_views,
cus.c.id,
metric,
case([
(metric <= p2, 3),
(and_(metric > p2, metric < p1), 2),
(metric >= p1, 1),
]).label("HML"),
]).select_from(cus).where(cus.week == week)