【问题标题】:asyncpg.exceptions.DataError: invalid input for query argument $1: 217027642536 (value out of int32 range)asyncpg.exceptions.DataError:查询参数 $1 的无效输入:217027642536(值超出 int32 范围)
【发布时间】:2020-08-13 22:39:00
【问题描述】:

我正在开发一个使用 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', DateTime),
    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]

我看不出这有什么问题。有人,请告诉我到底发生了什么?

【问题讨论】:

    标签: python postgresql sqlalchemy fastapi pydantic


    【解决方案1】:

    你基本上是整数溢出,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', DateTime),
        Column('market_cap', BigInteger)
    )                        ^^^^^^^^^^
    

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

    【讨论】:

    • 非常感谢您!但是使用 BigInteger 后我仍然收到错误
    • 是的,我是。是一样的
    • 如果您有 pgadmin,您可以确认您的表仍然对该列使用整数类型,因为它是以这种方式创建的,您应该再次更改列数据类型,或者如果您在该表中没有数据,您可以重新创建它。
    • 嗯,没错。让我尝试重新创建
    • 要更改列类型,您可以使用ALTER TABLE currencies ALTER COLUMN market_cap TYPE bigint
    猜你喜欢
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多