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

Python asyncpg.exceptions.DataError:查询参数$1的输入无效:217027642536(值超出int32范围),python,postgresql,sqlalchemy,fastapi,pydantic,Python,Postgresql,Sqlalchemy,Fastapi,Pydantic,我正在从事一个项目,该项目与Pydantic和SQLAlchemy一起使用FastAPI。我还使用encode/databases来管理数据库连接。但出于某种奇怪的原因,每当我尝试保存到数据库时,我都会得到asyncpg.exceptions.DataError:查询参数$1的输入无效:217027642536(值超出int32范围)。我的代码是这样的: database.py ... ... currencies = Table( 'currencies', metadata,

我正在从事一个项目,该项目与Pydantic和SQLAlchemy一起使用FastAPI。我还使用encode/databases来管理数据库连接。但出于某种奇怪的原因,每当我尝试保存到数据库时,我都会得到
asyncpg.exceptions.DataError:查询参数$1的输入无效:217027642536(值超出int32范围)
。我的代码是这样的:

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)
...
...
async def add_currency(payload: Currency):
    query = currencies.insert().values(**payload.dict())
    return await database.execute(query=query)
...
...
@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
...
...
class Currency(BaseModel):
    name: str
    price: float
    price_date: datetime
    price_timestamp: datetime
    market_cap: int


class CurrencyOutput(Currency):
    id: int
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]
database\u manager.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)
...
...
async def add_currency(payload: Currency):
    query = currencies.insert().values(**payload.dict())
    return await database.execute(query=query)
...
...
@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
...
...
class Currency(BaseModel):
    name: str
    price: float
    price_date: datetime
    price_timestamp: datetime
    market_cap: int


class CurrencyOutput(Currency):
    id: int
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]
endpoints.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)
...
...
async def add_currency(payload: Currency):
    query = currencies.insert().values(**payload.dict())
    return await database.execute(query=query)
...
...
@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
...
...
class Currency(BaseModel):
    name: str
    price: float
    price_date: datetime
    price_timestamp: datetime
    market_cap: int


class CurrencyOutput(Currency):
    id: int
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]
models.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)
...
...
async def add_currency(payload: Currency):
    query = currencies.insert().values(**payload.dict())
    return await database.execute(query=query)
...
...
@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
...
...
class Currency(BaseModel):
    name: str
    price: float
    price_date: datetime
    price_timestamp: datetime
    market_cap: int


class CurrencyOutput(Currency):
    id: int
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]
services.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)
...
...
async def add_currency(payload: Currency):
    query = currencies.insert().values(**payload.dict())
    return await database.execute(query=query)
...
...
@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
...
...
class Currency(BaseModel):
    name: str
    price: float
    price_date: datetime
    price_timestamp: datetime
    market_cap: int


class CurrencyOutput(Currency):
    id: int
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
,它可以存储范围为负值和正值的值9223372036854775807

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更改market的列类型应该可以解决问题,但请注意,较大的类型会占用更多内存。

非常感谢!但是在使用BigIntegeries之后,我仍然得到了错误,我是。这是一样的如果你有pgadmin,你可以确认你的表仍然使用该列的整数类型,因为它是以这种方式创建的,你应该再次更改列数据类型,或者如果你在该表中没有数据,你可以重新创建它。嗯,这是真的。让我尝试重新创建更改columntype您可以使用
ALTER TABLE currencies ALTER COLUMN market\u cap TYPE bigint