python - SQLAlchemy 和 SQLite 中的非常长整数

标签 python sqlite sqlalchemy integer-overflow

我正在使用 sqlite 数据库在 sqlalchemy 中处理非常长的整数(例如 2100000000000000000000)。错误:“Python int 太大,无法转换为 SQLite INTEGER”。

stackoverflow 中的答案建议使用字符串,但我考虑使用 numeric(scale=0)。使用数字有什么缺点吗?

from sqlalchemy import create_engine, MetaData, Table, Integer, Column, String, Numeric

meta_sl = MetaData()
engine = create_engine('sqlite:///testint.db')
conn_sl = engine.connect()

example = Table('example', meta_sl,
                Column('id', Integer, primary_key=True),
                Column('int', Integer),
                Column('str', String),
                Column('num', Numeric(scale=0)))

meta_sl.create_all(engine)

ins = example.insert()
my_int = 2100000000000000000000
try:
    conn_sl.execute(ins, {"id": 2,
                          "int": my_int,  # causes error!
                          "str": str(my_int),  # workaround nr.1
                          "num": my_int})  # workaround nr.2
except OverflowError:
    conn_sl.execute(ins, {"id": 2,
                          "str": str(my_int),  # workaround nr.1
                          "num": my_int})  # workaround nr.2

最佳答案

Are there any disadvantages using numeric?

是的,因为它并不总是有效。

SQLite documentation 中所述:

If the TEXT value is a well-formed integer literal that is too large to fit in a 64-bit signed integer, it is converted to REAL. For conversions between TEXT and REAL storage classes, only the first 15 significant decimal digits of the number are preserved.

因此,在您的特定情况下,使用 Numeric(scale=0) 似乎没问题......

ins = example.insert()
my_int = 2100000000000000000000
with engine.begin() as conn_sl:
    conn_sl.execute(
        ins,
        {
            "id": 2,
            # "int": my_int,  # causes error!
            "str": str(my_int),  # workaround nr.1
            "num": my_int,  # workaround nr.2
        },
    )
with engine.begin() as conn_sl:
    result = conn_sl.execute(sa.select(example.c.num)).fetchall()
    print(result)
    # [(Decimal('2100000000000000000000'),)]

...但 SQLAlchemy 还警告说

Dialect sqlite+pysqlite does not support Decimal objects natively, and SQLAlchemy must convert from floating point - rounding errors and other issues may occur. Please consider storing Decimal numbers as strings or integers on this platform for lossless storage.

例如,如果我们使用 my_int = 1234567890123456789012,它将作为 Decimal('1234567890123456774144') 往返。

关于python - SQLAlchemy 和 SQLite 中的非常长整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68417903/

相关文章:

Sqlite - 从多个表中自动删除

caching - SQLAlchemy 是否支持缓存?

python - 将子查询与其父查询隔离

javascript - HTML 中弹出消息的函数

python - django/python : Google doc viewer issue with . docx/.xlsx/.pptx

python - 如何分析 Django channel ?

Python:将以特定行为边界的 block 复制到新文件

php - 从 sqlite pdo 获取数组与 php 连接查询

python - 我如何对这个 View 进行 json 编码?

python - javascript 中的 OnChange 或 OnBlur 事件在 Django 中运行 python 函数并返回结果?