Chuyển đổi SQLAlchemy ORM thành gấu trúc DataFrame


107

Chủ đề này đã không được giải quyết trong một thời gian, ở đây hoặc ở nơi khác. Có giải pháp nào chuyển đổi SQLAlchemy <Query object>thành DataFrame gấu trúc không?

Pandas có khả năng sử dụng pandas.read_sqlnhưng điều này yêu cầu sử dụng SQL thô. Tôi có hai lý do để muốn tránh nó: 1) Tôi đã có tất cả mọi thứ bằng cách sử dụng ORM (một lý do chính đáng trong và của chính nó) và 2) Tôi đang sử dụng danh sách python như một phần của truy vấn (ví dụ: .db.session.query(Item).filter(Item.symbol.in_(add_symbols)ở đâu Itemlà lớp mô hình của tôi và add_symbolslà một danh sách). Đây là tương đương với SQL SELECT ... from ... WHERE ... IN.

Có bất cứ điều gì có thể?

Câu trả lời:


192

Dưới đây sẽ hoạt động trong hầu hết các trường hợp:

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

Xem pandas.read_sqltài liệu để biết thêm thông tin về các thông số.


@van +1 nhưng có thể làm với một chút chi tiết hơn. ví dụ: tôi đã làm df = pd.read_sql(query, query.bind)khi nào querylà một sqlalchemy.sql.selectable.Select. Nếu không, tôi có 'Select' object has no attribute 'session'.
Little Bobby Tables

Để sao chép-dán, tôi đã thêm liên kết đến các tài liệu hướng dẫn trực tiếp trong câu trả lời, trong đó bao gồm câu hỏi của bạn: bạn nên cung cấp các conthông số, có thể là enginehayconnection string
van

@van Sẽ tốt hơn nếu sử dụng query.session.connection () ở đây? Nếu không, truy vấn không tính đến các thay đổi không được hỗ trợ trong phiên ...
dataflow

1
@dataflow: Tôi nghĩ bạn đúng, nhưng tôi chưa bao giờ thử nghiệm giả định.
van

@van - điều này ném 'TypeError: mục trình tự 0: chuỗi mong đợi, tìm thấy DefaultMeta'; đã vò đầu bứt tóc cả ngày để tìm hiểu xem có chuyện gì không. Chỉ có điều tôi có thể con số là nó có thể có một cái gì đó để làm với cố gắng để trích xuất một kết nối từ một scoped_session ....
andrewpederson

85

Chỉ để làm rõ hơn điều này cho các lập trình viên gấu trúc mới làm quen, đây là một ví dụ cụ thể,

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

Ở đây, chúng tôi chọn một đơn khiếu nại từ bảng khiếu nại (mô hình sqlalchemy là Khiếu nại) với id = 2


1
Tôi nghĩ điều này rõ ràng hơn, khi mã dựa trên ORM.
user40780 19/09/17

CHÚA ƠI! Tôi đã đấu tranh với địa ngục sqlAlchemy rất nhiều. Chỉ là một lưu ý phụ ở đây: Bạn cũng có thể viết read_sql ('CHỌN * TỪ TABLENAME', db.session.bind). Cảm ơn. Câu trả lời trên đã giúp tôi nhiều hơn câu trả lời được chấp nhận.
PallavBakshi

3
Làm gì .statement?
bạch đậu khấu

4
@cardamom nó trả về truy vấn sql.
Nuno André

10

Giải pháp đã chọn không phù hợp với tôi, vì tôi liên tục gặp lỗi

AttributeError: Đối tượng 'AnnotatedSelect' không có thuộc tính 'low'

Tôi thấy những điều sau đây đã hoạt động:

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

4

Nếu bạn muốn biên dịch một truy vấn với các tham số và đối số phương ngữ cụ thể, hãy sử dụng một cái gì đó như sau:

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)

Việc nhập khẩu selecttrong df_query = select([DailyTrendsTable])là mất tích. from sqlalchemy import select
Carlos Azevedo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.