SQLAlchemy ORM을 Panda DataFrame으로 변환
SQL을 ?<Query object>
판다 데이터 프레임에?
판다는 사용할 수 있는 능력이 있습니다.pandas.read_sql
그러나 이를 위해서는 원시 SQL을 사용해야 합니다.저는 그것을 피하고 싶은 두 가지 이유가 있습니다.
- 저는 이미 ORM을 사용하는 모든 것을 가지고 있습니다(그 자체로 충분한 이유).
- 쿼리의 일부로 파이썬 목록을 사용하고 있습니다. 예:
db.session.query(Item).filter(Item.symbol.in_(add_symbols)
Item
저의 모델 수업이고add_symbols
는 목록입니다.은 SQL의 SQL에 합니다.SELECT ... from ... WHERE ... IN
.
가능한 일이 있습니까?
대부분의 경우 다음과 같이 작동합니다.
df = pd.read_sql(query.statement, query.session.bind)
매개 변수에 대한 자세한 내용은 설명서를 참조하십시오.
초보 판다 프로그래머들을 위해 이것을 좀 더 분명히 하기 위해, 여기 구체적인 예가 있습니다.
pd.read_sql(session.query(Complaint).filter(Complaint.id == 2).statement,session.bind)
여기에서는 불만 표(Sqlalchemy 모델은 불만 사항)에서 ID가 = 2인 불만 사항을 선택합니다.
완전성을 위해:Pandas-함수 대신 Pandas-DataFrame-함수를 사용하여 다음을 변환할 수도 있습니다.structured or record ndarray to DataFrame
.
예를 들어 SQLLchemy에서 쿼리를 이미 실행하고 결과를 이미 사용할 수 있는 경우에 유용합니다.
import pandas as pd
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:postgres@localhost:5432/my_database'
engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True, echo=False)
db = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base = declarative_base(bind=engine)
class Currency(Base):
"""The `Currency`-table"""
__tablename__ = "currency"
__table_args__ = {"schema": "data"}
id = Column(Integer, primary_key=True, nullable=False)
name = Column(String(64), nullable=False)
# Defining the SQLAlchemy-query
currency_query = db.query(Currency).with_entities(Currency.id, Currency.name)
# Getting all the entries via SQLAlchemy
currencies = currency_query.all()
# We provide also the (alternate) column names and set the index here,
# renaming the column `id` to `currency__id`
df_from_records = pd.DataFrame.from_records(currencies
, index='currency__id'
, columns=['currency__id', 'name'])
print(df_from_records.head(5))
# Or getting the entries via Pandas instead of SQLAlchemy using the
# aforementioned function `read_sql_query()`. We can set the index-columns here as well
df_from_query = pd.read_sql_query(currency_query.statement, db.bind, index_col='id')
# Renaming the index-column(s) from `id` to `currency__id` needs another statement
df_from_query.index.rename(name='currency__id', inplace=True)
print(df_from_query.head(5))
계속 오류가 발생하여 선택한 솔루션이 작동하지 않았습니다.
특성 오류: '주석 있음Select' 개체에 'lower' 특성이 없습니다.
다음과 같은 것들이 효과가 있었습니다.
df = pd.read_sql_query(query.statement, engine)
매개 변수 및 방언 관련 인수를 사용하여 쿼리를 컴파일하려면 다음과 같은 방법을 사용합니다.
c = query.statement.compile(query.session.bind)
df = pandas.read_sql(c.string, query.session.bind, params=c.params)
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)
2.0 SQLalchemy
가능) 1.4에서도 할 수 있습니다.future=True
는 것으로 .pd.read_sql
아직 구현되지 않았으며 다음과 같은 문제가 발생합니다.
NotImplementedError: This method is not implemented for SQLAlchemy 2.0.
이것은 판다 2.0까지 해결되지 않을 미해결 문제입니다. 여기와 여기에서 이에 대한 몇 가지 정보를 찾을 수 있습니다.
만족할 만한 해결 방법을 찾지 못했지만, 일부 사람들은 엔진의 두 가지 구성을 사용하는 것 같습니다. 하나는 future false 플래그가 있는 것입니다.
engine2 = create_engine(URL_string, echo=False, future=False)
문자열을 쿼리하면 이 솔루션은 괜찮지만 ORM을 사용하면 아직 최적화되지 않은 사용자 지정 함수를 사용할 수 있는 최선의 방법은 다음과 같습니다.
Conditions = session.query(ExampleTable)
def df_from_sql(query):
return pd.DataFrame([i.__dict__ for i in query]).drop(columns='_sa_instance_state')
df = df_from_sql(ExampleTable)
이 솔루션은 pd.read_sql이 새 구문을 구현할 때까지 임시 솔루션입니다.
ORM을 사용하는 경우 다음과 같이 간단합니다.
pd.DataFrame([r._asdict() for r in query.all()])
의 좋은 pd.read_sql
SQL 및 세션을 비즈니스 로직 코드에 노출하지 않으려는 경우.
https://stackoverflow.com/a/52208023/1635525 에서 찾을 수 있습니다.
를 사용한 간단한 예Result.keys()
열 이름을 가져오는 방법입니다.
import sqlalchemy as sa
import pandas as pd
engine = sa.create_engine(...)
with engine.connect() as conn:
result = conn.execute("SELECT * FROM foo;")
df = pd.DataFrame(result.all(), columns=result.keys())
https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.Result.keys
이 답변은 SQL Alchemy를 사용하여 재현 가능한 예제를 제공합니다.select
진술 및 판다 데이터 프레임을 반환합니다.데이터베이스 엔진을 설치하지 않고도 누구나 복제할 수 있도록 인메모리 SQLite 데이터베이스를 기반으로 합니다.
import pandas
from sqlalchemy import create_engine
from sqlalchemy import MetaData, Table, Column, Text
from sqlalchemy.orm import Session
테이블 메타데이터 정의 및 테이블 만들기
engine = create_engine('sqlite://')
meta = MetaData()
meta.bind = engine
user_table = Table('user', meta,
Column("name", Text),
Column("full_name", Text))
user_table.create()
데이터를 에 삽입합니다.user
테이블
stmt = user_table.insert().values(name='Bob', full_name='Sponge Bob')
with Session(engine) as session:
result = session.execute(stmt)
session.commit()
선택한 문장의 결과를 판다 데이터 프레임으로 읽어 들입니다.
# Select data into a pandas data frame
stmt = user_table.select().where(user_table.c.name == 'Bob')
df = pandas.read_sql_query(stmt, engine)
df
Out:
name full_name
0 Bob Sponge Bob
SQL 쿼리를 사용하는 경우
def generate_df_from_sqlquery(query):
from pandas import DataFrame
query = db.session.execute(query)
df = DataFrame(query.fetchall())
if len(df) > 0:
df.columns = query.keys()
else:
columns = query.keys()
df = pd.DataFrame(columns=columns)
return df
profile_df = generate_df_from_sqlquery(profile_query)
다음을 사용하여 답변에 추가read_sql
@van과 마찬가지로, 내 쿼리가 조인과 관련되었을 때, sqlalchemy는 예를 들어 조인 테이블과 기본 테이블이 모두 id 열을 가질 경우 id_1, id_2와 같은 조인 테이블의 별칭 열을 암시적으로 추가하는 것처럼 보였습니다..all()을 사용하면 결과를 반환하기 전에 이러한 암시적 열이 제거되지만read_sql
이 열을 포함합니다.
그 경우에 대한 해결책은 제가 선택한 항목에 명시적으로 설명하는 것이었습니다.그래서 교체했습니다.
query = session.query(model)
와 함께
query = session.query(model.col_1, model.col_2)
또는 모두 선택할 수 있습니다.
query = session.query(*model.__table__.columns.values())
그리고나서
df = pd.read_sql(query.statement, query.session.bind)
스칼케미 필터링 후 데이터를 이미 수신한 경우 이를 수행하는 또 다른 방법이 여기에 표시됩니다. 다음과 같이 대답한 후 다음 기능을 사용하십시오.
from collections import defaultdict
from sqlalchemy import inspect
import pandas as pd
def query_to_dict(rest):
result = defaultdict(list)
for obj in rest:
instance = inspect(obj)
for key, x in instance.attrs.items():
result[key].append(x.value)
return result
# Getting all the entries via SQLAlchemy
currencies = currency_query.all()
df = pd.DataFrame(query_to_dict(rset))
2023년에 제게 도움이 되었습니다. 먼저 엔진과 세션을 생성하고 쿼리 문자열을 SQL 연금술 텍스트로 변환합니다.
from sqlalchemy import text
engine = create_engine(path, echo=True)
Session = sessionmaker(bind=engine)
session = Session()
# generates suitble text for SQLalchemy
sql = text(query_string)
session.execute(sql)
df = pd.read_sql_query(sql=sql, con=engine.connect())
팬더를 PD로 수입합니다.
users = Users.query.all 명령
df = pd.데이터 프레임(사용자)
인쇄(df)
언급URL : https://stackoverflow.com/questions/29525808/sqlalchemy-orm-conversion-to-pandas-dataframe
'source' 카테고리의 다른 글
MongoDB에서 수집이 중단되면 인덱스도 자동으로 삭제됩니까? (0) | 2023.06.28 |
---|---|
테이블 값 함수 실행 방법 (0) | 2023.06.28 |
C#에서 저장 프로시저를 큰 CLOB로 호출하는 문제 발생 (0) | 2023.06.28 |
Mariadb: OFFSET 및 LIMIT를 사용하는 페이지가 한 행을 건너뜁니다. (0) | 2023.06.28 |
2개의 열을 기준으로 SQL 고유 제약 조건을 만들려면 어떻게 해야 합니까? (0) | 2023.06.23 |