SQLAlchemy ORM转换为Pandas DataFrame


107

这个话题已经有一段时间没有在这里或其他地方了。是否有将SQLAlchemy <Query object>转换为pandas DataFrame 的解决方案?

Pandas具有使用能力,pandas.read_sql但这需要使用原始SQL。我有两个避免发生这种情况的原因:1)我已经使用ORM拥有了一切(本身就是一个很好的理由),并且2)我正在使用python列表作为查询的一部分(例如:模型类.db.session.query(Item).filter(Item.symbol.in_(add_symbols)在哪里Item)并且add_symbols是列表)。这等效于SQL SELECT ... from ... WHERE ... IN

有什么可能吗?

Answers:


192

在大多数情况下,下面的代码应该有效:

df = pd.read_sql(query.statement, query.session.bind)

有关pandas.read_sql参数的更多信息,请参见文档。


@van +1,但可以做更多细节。比如我做df = pd.read_sql(query, query.bind)的时候query是一个sqlalchemy.sql.selectable.Select。否则,我就知道了'Select' object has no attribute 'session'
小鲍比表

为了复制粘贴,我在答案中直接添加了指向文档的链接,其中涵盖了您的问题:您应该提供con参数,可以为engineorconnection string
van

@van在这里使用query.session.connection()会更好吗?否则,查询将不考虑会话中的持久变化...
数据流

1
@dataflow:我认为您是对的,但我从未检验过这个假设。
面包车

@van-抛出“ TypeError:序列项0:期望的字符串,找到DefaultMeta”;整天都在扯我的头发,试图找出问题所在。我唯一能想到的是,它可能与尝试从scoped_session中提取连接有关……
andrewpederson

85

为了让新手熊猫程序员更加清楚,这是一个具体示例,

pd.read_sql(session.query(Complaint).filter(Complaint.id == 2).statement,session.bind) 

在这里,我们从id = 2的投诉表(sqlalchemy模型为Complaint)中选择一个投诉


1
当代码基于ORM时,我认为这更加清楚。
user40780

我的天啊!我在sqlAlchemy地狱中挣扎很多。这里只是一个小注:您还可以编写read_sql('SELECT * FROM TABLENAME',db.session.bind)。谢谢。上面的答案对我的帮助超过了公认的答案。
PallavBakshi

3
怎么.statement办?
cardamom

4
@cardamom它返回sql查询。
NunoAndré18年

10

所选解决方案对我不起作用,因为我不断收到错误消息

AttributeError:'AnnotatedSelect'对象没有属性'lower'

我发现以下工作:

df = pd.read_sql_query(query.statement, engine)

4

如果要使用参数编译查询并说方言特定的参数,请使用以下命令:

c = query.statement.compile(query.session.bind)
df = pandas.read_sql(c.string, query.session.bind, params=c.params)

3
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

engine = create_engine('postgresql://postgres:postgres@localhost:5432/DB', echo=False)
Base = declarative_base(bind=engine)
Session = sessionmaker(bind=engine)
session = Session()

conn = session.bind

class DailyTrendsTable(Base):

    __tablename__ = 'trends'
    __table_args__ = ({"schema": 'mf_analysis'})

    company_code = Column(DOUBLE_PRECISION, primary_key=True)
    rt_bullish_trending = Column(Integer)
    rt_bearish_trending = Column(Integer)
    rt_bullish_non_trending = Column(Integer)
    rt_bearish_non_trending = Column(Integer)
    gen_date = Column(Date, primary_key=True)

df_query = select([DailyTrendsTable])

df_data = pd.read_sql(rt_daily_query, con = conn)

selectin 的导入df_query = select([DailyTrendsTable])丢失。from sqlalchemy import select
卡洛斯·阿兹维多
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.