asyncpg.exceptions.DataError:查询参数$ 1的输入无效:217027642536值超出int32范围

问题描述

我正在研究一个将FastAPI与Pydantic和sqlAlchemy一起使用的项目。我还使用编码/数据库来管理数据库连接。但是出于某些奇怪的原因,我每次尝试保存到数据库时都会得到asyncpg.exceptions.DataError: invalid input for query argument $1: 217027642536 (value out of int32 range)。这是我的代码

database.py

...
...
currencies = Table(
    'currencies',Metadata,Column('id',Integer,primary_key=True),Column('name',String(50)),Column('price',Float),Column('price_date',DateTime),Column('price_timestamp',Column('market_cap',Integer)
)

database = Database(DATABASE_URL)

database_manager.py

...
...
async def add_currency(payload: Currency):
    query = currencies.insert().values(**payload.dict())
    return await database.execute(query=query)

endpoints.py

...
...
@endpoints.post('/',response_model=CurrencyOutput,status_code=201)
async def add_currency():
    data = check_currency_price()

    payload = Currency(
        name=data['name'],price=data['price'],price_date=data['price_date'],price_timestamp=data['price_timestamp'],market_cap=data['market_cap']
    )

    currency_id = await database_manager.add_currency(payload)
    response = {
        'id': currency_id,**payload.dict()
    }

    return response

models.py

...
...
class Currency(BaseModel):
    name: str
    price: float
    price_date: datetime
    price_timestamp: datetime
    market_cap: int


class CurrencyOutput(Currency):
    id: int

services.py

def check_currency_price():
    response = httpx.get(
        'https://api.nomics.com/v1/currencies/ticker?' +
        'key=somerandomAPIkey&ids=BTC&interval=1d,30d&convert=USD'
    )

    return response.json()[0]

我看不出有什么问题。有人,请告诉我到底是怎么回事?

解决方法

您基本上有整数溢出, Int32 代表2^31 - 1,这意味着它可以将值存储在 -2147483648到2147483648 范围内,但是您是尝试插入的内容大于2^31

2**31 > 217027642536
Out: False

因此,您需要使用SQLAlchemy的 BigInteger 类型表示 Int64 ,它还表示2^63 - 1,它可以将值存储在负数和正数范围内 9,223,372,036,854,775,807

from sqlalchemy import BigInteger

currencies = Table(
    'currencies',metadata,Column('id',Integer,primary_key=True),Column('name',String(50)),Column('price',Float),Column('price_date',DateTime),Column('price_timestamp',Column('market_cap',BigInteger)
)                        ^^^^^^^^^^

使用 BigInteger 更改市场的列类型应该可以解决该问题,但请注意,较大的类型使用更多的内存。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...