Тип NUMERIC
Тип NUMERIC создает колонку для хранения
точных десятичных чисел. Он используется для
денежных сумм, цен, процентов и других значений,
где важна точность и недопустимы ошибки округления,
возникающие при работе с Float. Первым
параметром передается общая точность precision,
а вторым - масштаб scale, то есть количество
цифр после запятой. Дополнительно можно указать
asdecimal, чтобы управлять тем, возвращать
значения как Decimal или как float.
Синтаксис
NUMERIC(precision, scale, [asdecimal])
Пример
Давайте создадим модель с колонкой типа
NUMERIC и посмотрим на итоговый SQL
запрос создания таблицы:
from sqlalchemy import create_engine, Numeric
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
num: Mapped[float] = mapped_column(Numeric(10, 2))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
from sqlalchemy.schema import CreateTable
print(CreateTable(Article.__table__).compile(engine))
Итоговый SQL запрос:
CREATE TABLE articles (
id INTEGER NOT NULL,
title VARCHAR NOT NULL,
num NUMERIC(10, 2) NOT NULL,
PRIMARY KEY (id)
)
Пример
Давайте запишем число в колонку NUMERIC
и прочитаем его обратно. По умолчанию значение
возвращается как Decimal:
from sqlalchemy import create_engine, Numeric, select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
num: Mapped[float] = mapped_column(Numeric(10, 2))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article', num=1234.50)
session.add(article)
session.commit()
with Session(engine) as session:
res = session.scalar(select(Article.num))
print(res)
print(type(res))
Результат выполнения кода:
1234.50
<class 'decimal.Decimal'>
Пример
Давайте отключим режим asdecimal,
чтобы значения возвращались как float:
from sqlalchemy import create_engine, Numeric, select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
num: Mapped[float] = mapped_column(Numeric(10, 2, asdecimal=False))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article', num=1234.50)
session.add(article)
session.commit()
with Session(engine) as session:
res = session.scalar(select(Article.num))
print(res)
print(type(res))
Результат выполнения кода:
1234.5
<class 'float'>