首页 > 解决方案 > Dataframe.read_sql_query() 与 SQL Alchemy 中的十进制类型的 TypeDecorator

问题描述

我已经用自定义类型 SqliteDecimal 在 SQLA 中声明了一个表。我正在努力将值检索到数据框中。返回类型是'numpy.float64',我期待一个十进制。我怀疑 TypeDecorator 不正确:

import decimal
from sqlalchemy import Column
import sqlalchemy.types as types
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import pandas as pd

Base = declarative_base()
engine = create_engine("sqlite://", echo=False)

装饰类:

class SqliteDecimal(types.TypeDecorator):

    """Decimal decorator converts b/w decimal and text in SQLite"""
    impl = types.String

    def load_dialect_impl(self, dialect):
        return dialect.type_descriptor(types.VARCHAR(100))

    def process_bind_param(self, value, dialect):
        return str(value)

    def process_result_value(self, value, dialect):
        if value in ["None", "NaN", "nan"]:
            result = decimal.Decimal("NaN")

        else:
            result = decimal.Decimal(value)

        return result

SQL炼金术表:

class MyTable(Base):

    __tablename__ = "my_table"
    number = Column(SqliteDecimal, primary_key=True)

主要的:

Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

row1 = MyTable(number=decimal.Decimal(1.1))
session.add(row1)
session.commit()
session.close()
query = session.query(MyTable)
df = pd.read_sql_query(query.statement, engine)
print(type(df.iloc[0,0]))

标签: pandassqlalchemy

解决方案


固定的。需要 coerce_float = False:

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

推荐阅读