我有一个包含列的表格 - id(int)
,date(DateTime)
,value(float)
。我想按日期输出具有id=2.
我为此编写了以下sql查询,并且查询工作正常:
select cast(date as date), avg(value) from table where id=2 group by cast(date as date)
对于同样的问题,如果我想在sqlalchemy中执行,我使用了以下表达式:
>> from sqlalchemy import sql, types
>> x = sql.cast(Table.date, types.Date)
但是当我尝试执行x时,我遇到了以下错误:
>> x.execute()
ArgumentError: Not an executable clause: CAST(Table.date AS DATETIME)
这意味着SQL Server正在考虑types.Date as DateTime
。
请忽略ArgumentError。我要关注的是内部SQL查询使用CAST(Table.date AS DATETIME)
而不是CAST(Table.date AS DATE)
有没有办法让我可以在sqlalchemy中将DateTime转换为Date?
答案 0 :(得分:0)
以下代码错误:
clause
。您需要有一个声明或查询(见下文)。这就是您最初错误的原因。sa.Date
,mssql
引擎将转为DATETIME
。我不完全确定为什么会这样,但我怀疑是因为旧版本的MSSQL没有单独的DATE
- 仅数据类型。要解决此问题,请将其简单地转换为DATE
方言中的mssql
数据类型。以下代码应该有效。我现在没有mssql
,但我确实显示了mssql
的SQL语句的汇编:
from sqlalchemy import create_engine, Column, Integer, Float, Date, DateTime, func
from sqlalchemy.dialects.mssql import DATE
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# @TODO: replace with your connection string
engine = create_engine('sqlite:///:memory:', echo=True)
Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base()
class MyTable(Base):
__tablename__ = 'my_table'
id = Column(Integer, primary_key=True)
date = Column(DateTime())
value = Column(Float())
Base.metadata.create_all(engine)
def get_mssql_sql(qry):
from sqlalchemy.dialects import mssql
dialect = mssql.dialect()
return str(qry.compile(dialect=dialect))
# DATE = Date # @note: this will not work in MSSQL (shows problem-2)
q = (session
.query(func.cast(MyTable.date, DATE), func.avg(MyTable.value))
.filter(MyTable.id == 2)
.group_by(func.cast(MyTable.date, DATE))
)
print(get_mssql_sql(q.statement))
# in your code, just run below to execute:
rows = q.all()