反映表时如何使sqlalchemy返回浮点数而不是十进制数?

jpk*_*tta 7 python sqlalchemy

我有一个在 Python 代码之外定义的 MySQL 数据库。我正在使用反射将其放入 SQLAlchemy,因此我没有任何可以修改的类定义。我不必担心会丢失精度,而且我在 Python 中对结果进行了一些算术运算,所以我宁愿不必手动将一堆值转换为浮点数或十进制数。

import sqlalchemy as sa

eng = sa.create_engine("mysql+pymysql://user:passwd@server/database")
eng.execute("create table if not exists foo (x double not null)")
eng.execute("insert into foo (x) values (0.1)")

md = sa.MetaData(bind=eng)
md.reflect()
foo = md.tables["foo"]

res = eng.execute(foo.select())
row = res.fetchone()
print(type(row.x))
print(repr(foo.c.x.type))
Run Code Online (Sandbox Code Playgroud)

输出:

<class 'decimal.Decimal'>
DOUBLE
Run Code Online (Sandbox Code Playgroud)

jpk*_*tta 6

使用this post中的建议,并且在设置asdecimal属性之前不使用反射表,我可以获得浮点数而不是小数。

import sqlalchemy as sa

eng = sa.create_engine("mysql+pymysql://chiptest:fryisthedevil@database/bench_drylake")
eng.execute("create table if not exists foo (x double not null)")
eng.execute("insert into foo (x) values (0.1)")

md = sa.MetaData(bind=eng)
md.reflect()
foo = md.tables["foo"]

# this needs to happen before any queries
for table in md.tables.values():
    for column in table.columns.values():
        if isinstance(column.type, sa.Numeric):
            column.type.asdecimal = False

res = eng.execute(foo.select())
row = res.fetchone()
print(type(row.x))
print(repr(foo.c.x.type))
Run Code Online (Sandbox Code Playgroud)

输出:

<class 'float'>
DOUBLE(asdecimal=False)
Run Code Online (Sandbox Code Playgroud)

注意:如果在设置之前对反射表进行查询asdecimal = Falsecolumn.type仍然显示为DOUBLE(asdecimal=False),但值的类型仍然是Decimal。我猜这是因为 SQLAlchemy 正在做某种缓存,但我现在不打算确定这一点。

  • 要在“SQLAlchemy”模型内部工作,您只需执行以下操作:https://gist.github.com/dennismonsewicz/f7fd9184a1950912d0ea (5认同)