将数据从sqlalchemy移动到pandas DataFram

2024-04-25 04:06:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在pandas数据帧中加载SQLAlchemy。在

当我这样做的时候:

df = pd.DataFrame(LPRRank.query.all())

我明白了

^{pr2}$

但是,我希望数据库中的每一列都成为数据帧中的一列:

0        M. Misty  1  18
1        P. Patch  2  18
...
...

当我试着:

dff = pd.read_sql_query(LPRRank.query.all(), db.session())

我得到一个属性错误:

AttributeError: 'SignallingSession' object has no attribute 'cursor'

以及

dff = pd.read_sql_query(LPRRank.query.all(), db.session)

同时给出一个错误:

AttributeError: 'scoped_session' object has no attribute 'cursor'

我用来生成对象列表的是:

app = Flask(__name__)
db = SQLAlchemy(app)

class LPRRank(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    candid = db.Column(db.String(40), index=True, unique=False)
    rank = db.Column(db.Integer, index=True, unique=False) 
    user_id = db.Column(db.Integer, db.ForeignKey('lprvote.id'))

    def __repr__(self):
        return '<{} || {} || {}>'.format(self.candid,
                                                 self.rank, self.user_id) 

这个问题: How to convert SQL Query result to PANDAS Data Structure? 是没有错误的,但是将每一行作为一个对象,这不是我想要的。我可以访问返回对象中的各个列,但似乎有更好的方法来访问它。在

文档位于pandas.pydata.org如果您已经了解了正在发生的事情,并且只需要检查语法就可以了。2016年4月20日的文件(1319页pdf)指出,pandas连接仍在p.872上进行实验。在

现在,SQLALCHEMY/PANDAS - SQLAlchemy reading column as CLOB for Pandas to_sql是关于指定SQL类型的。我的是SQLAlchemy,这是默认的。在

并且,sqlalchemy pandas to_sql OperationalErrorWriting to MySQL database with pandas using SQLAlchemy, to_sql,和SQLAlchemy/pandas to_sql for SQLServer -- CREATE TABLE in master db是关于写入SQL数据库,这会产生一个操作错误,一个数据库错误,和一个“创建表”错误,这些都不是我的问题。在

这个,SQLAlchemy Pandas read_sql from jsonb想要一个jsonb属性给列:而不是我的茶杯。在

前面的问题SQLAlchemy ORM conversion to pandas DataFrame解决了我的问题,但是解决方案:使用query.session.bind不是我的解决方案。我正在和数据库会话添加(),和数据库会话提交(),但当我使用第二个答案中指定的db.session.bind时,我得到一个属性错误:

AttributeError: 'list' object has no attribute '_execute_on_connection'

Tags: toselfid数据库pandasdbsqlsqlalchemy
2条回答

冻糕的答案是好的,但也有一些问题:

  1. 效率每个对象的创建都意味着将数据复制到一个数据帧中,因此创建一个数据帧列表可能需要时间
  2. 不镜像具有行集合的数据帧

因此,下面的例子提供了一个parent类,它被同化为一个数据帧表示,一个child类被同化到给定数据帧的。在

下面的代码提供了两种获取dataframe的方法,dataframe对象只在需要时创建,不会浪费cpu和内存。在

如果在创建时需要dataframe,则只需添加构造函数(def __init__(self, rows:List[MyDataFrameRow] = None)...)并创建一个新属性并分配self.data_frame的结果。在

from pandas import DataFrame, read_sql
from sqlalchemy import Column, Integer, String, Float, ForeignKey
from sqlalchemy.orm import relationship, Session

Base = declarative_base()

class MyDataFrame(Base):
    __tablename__ = 'my_data_frame'
    id = Column(Integer, primary_key=True)
    rows = relationship('MyDataFrameRow', cascade='all,delete')

    @property
    def data_frame(self) -> DataFrame:
        columns = GenomeCoverageRow.data_frame_columns()
        return DataFrame([[getattr(row, column) for column in columns] for row in self.rows],
                         columns=columns)

    @staticmethod
    def to_data_frame(identifier: int, session: Session) -> DataFrame:
        query = session.query(MyDataFrameRow).join(MyDataFrame).filter(MyDataFrame.id == identifier)
        return read_sql(query.statement, session.get_bind())


class MyDataFrameRow(Base):

    __tablename__ = 'my_data_row'
    id = Column(Integer, primary_key=True)
    name= Column(String)
    age= Column(Integer)
    number_of_children = Column(Integer)
    height= Column(Integer)
    parent_id = Column(Integer, ForeignKey('my_data_frame.id'))

    @staticmethod
    def data_frame_columns() -> Tuple[Any]:
        return tuple(column.name for column in GenomeCoverageRow.__table__.columns if len(column.foreign_keys) == 0
                     and column.primary_key is False)
...
session = Session(...)
df1 = MyDataFrame.to_data_frame(1,session)
my_table_obj = session.query(MyDataFrame).filter(MyDataFrame.id == 1).one()
df2 = my_table_obj.data_frame

只需在模型中添加一个__init__方法,并在构建dataframe之前调用Class对象。下面特别创建了一个元组的iterable,这些元组用pandas.DataFrame()绑定到列中。在

class LPRRank(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    candid = db.Column(db.String(40), index=True, unique=False)
    rank = db.Column(db.Integer, index=True, unique=False) 
    user_id = db.Column(db.Integer, db.ForeignKey('lprvote.id'))

    def __init__(self, candid=None, rank=None, user_id=None):
        self.data = (candid, rank, user_id)

    def __repr__(self):
        return (self.candid, self.rank, self.user_id) 

data = db.session.query(LPRRank).all()
df = pd.DataFrame([(d.candid, d.rank, d.user_id) for d in data], 
                  columns=['candid', 'rank', 'user_id'])

或者,使用基于您定义的模型类的SQLAlchemy ORM运行read_sql

^{pr2}$

相关问题 更多 >