Pandalar DataFrame'e SQLAlchemy ORM dönüşümü


107

Bu konu bir süredir burada veya başka bir yerde ele alınmadı. Bir SQLAlchemy'yi <Query object>Pandalar DataFrame'e dönüştüren bir çözüm var mı ?

Pandaların kullanma yeteneği vardır, pandas.read_sqlancak bu ham SQL kullanımını gerektirir. Bundan kaçınmak için iki nedenim var: 1) ORM'yi kullanan her şeye zaten sahibim (kendi başına iyi bir neden) ve 2) Sorgunun bir parçası olarak python listeleri kullanıyorum (örneğin: model sınıfım .db.session.query(Item).filter(Item.symbol.in_(add_symbols)nerede Itemve add_symbolsbir listedir). Bu, SQL'in eşdeğeridir SELECT ... from ... WHERE ... IN.

Herhangi bir şey mümkün mü?

Yanıtlar:


193

Çoğu durumda aşağıda çalışmalıdır:

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

pandas.read_sqlParametreler hakkında daha fazla bilgi için belgelere bakın .


@van +1 ama biraz daha fazla ayrıntıyla yapabilirdi. örneğin ne df = pd.read_sql(query, query.bind)zaman yaptım querya sqlalchemy.sql.selectable.Select. Aksi takdirde aldım 'Select' object has no attribute 'session'.
Little Bobby Tablolar

Kopyalayıp yapıştırmak için, dokümantasyonun doğrudan cevabına sorunuzu kapsayan bağlantı ekledim: orconengineconnection string
van

@van Burada query.session.connection () kullanmak daha iyi olur mu? Aksi takdirde sorgu, oturumdaki karşı konulmamış değişiklikleri hesaba katmaz ...
dataflow

1
@dataflow: Sanırım haklısın, ama varsayımı hiç test etmedim.
van

@van - bu 'TypeError: sıra öğesi 0: beklenen dize, DefaultMeta bulundu' atar; neyin yanlış olduğunu anlamaya çalışırken bütün gün saçımı yırtıp atıyorum. Anlayabildiğim tek şey, bunun kapsamlı bir oturumdan bir bağlantı çıkarmaya çalışmakla bir ilgisi olabileceğidir ....
andrewpederson

87

Bunu acemi pandalar programcıları için daha net hale getirmek için işte somut bir örnek:

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

Burada şikayet tablosundan (sqlalchemy modeli Complaint) id = 2 olan bir şikayet seçiyoruz.


1
Kod ORM tabanlı olduğunda bunun daha açık olduğunu düşünüyorum.
user40780

AMAN TANRIM! SqlAlchemy ile cehennemle çok mücadele ettim. Burada sadece bir ek not: Read_sql ('TABLENAME'DEN SEÇİN *', db.session.bind) da yazabilirsiniz. Teşekkürler. Yukarıdaki cevap bana kabul edilenden daha fazla yardımcı oldu.
PallavBakshi

3
Ne anlama geliyor .statement?
cardamom

4
@cardamom sql sorgusunu döndürür.
Nuno André

10

Hatayı almaya devam ettiğim için seçilen çözüm benim için işe yaramadı

AttributeError: 'AnnotatedSelect' nesnesinin 'alt' niteliği yok

Aşağıdakilerin işe yaradığını buldum:

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

4

Parametrelerle ve diyalekt özel argümanlarla bir sorgu derlemek istiyorsanız, şuna benzer bir şey kullanın:

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)

İthalat selectin df_query = select([DailyTrendsTable])eksik. from sqlalchemy import select
Carlos Azevedo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.