Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NumericField make #1691

Open
daeeros opened this issue Aug 6, 2024 · 5 comments
Open

NumericField make #1691

daeeros opened this issue Aug 6, 2024 · 5 comments

Comments

@daeeros
Copy link

daeeros commented Aug 6, 2024

I would like to create a numericfield that is floatless and has a large limit, allowing me to store giant numbers. But how to make one on tortoise can you tell me? Here is my old implementation on peewee

class NumericField(pw.DecimalField):
    def get_modifiers(self):
        pass
    
    def python_value(self, value):
        # Convert the decimal value to int before returning
        if value is not None:
            return int(value)
        return value

test = NumericField(default=10000)
@waketzheng
Copy link
Contributor

How about BigIntField

@daeeros
Copy link
Author

daeeros commented Aug 15, 2024

How about BigIntField

They have max 9,223,372,036,854,775,807. Sometime i need bigger then this value to store(

@waketzheng
Copy link
Contributor

@daeeros A sample for you:

from typing import Any, Type

from tortoise import run_async
from tortoise.contrib.test import init_memory_sqlite
from tortoise.fields import Field, IntField
from tortoise.fields.data import SqlTypes, Term, functions
from tortoise.models import Model


class BigBigIntField(Field[int], int):
    SQL_TYPE = "DECIMAL(40,0)"

    def to_python_value(self, value: Any) -> int | None:
        self.validate(value)
        if value is not None:
            value = int(value)
        return value

    def to_db_value(self, value: Any, instance: Type[Model] | Model) -> str | None:
        if value is not None:
            value = str(value)
        self.validate(value)
        return value

    class _db_sqlite:
        SQL_TYPE = "VARCHAR(40)"

        def function_cast(self, term: Term) -> Term:
            return functions.Cast(term, SqlTypes.NUMERIC)


class User(Model):
    id = IntField(pk=True)
    money = BigBigIntField(default=10000)


@init_memory_sqlite
async def main() -> None:
    u = await User.create()
    print(u.money)
    a = 9_223_372_036_854_775_807
    u = await User.create(money=a * 10)
    print(u.money)
    print(f"{type(u.money)= }")
    assert u.money == a * 10


if __name__ == "__main__":
    run_async(main())

Pass test with sqlite and mysql.

@daeeros
Copy link
Author

daeeros commented Aug 17, 2024

@daeeros A sample for you:

from typing import Any, Type

from tortoise import run_async
from tortoise.contrib.test import init_memory_sqlite
from tortoise.fields import Field, IntField
from tortoise.fields.data import SqlTypes, Term, functions
from tortoise.models import Model


class BigBigIntField(Field[int], int):
    SQL_TYPE = "DECIMAL(40,0)"

    def to_python_value(self, value: Any) -> int | None:
        self.validate(value)
        if value is not None:
            value = int(value)
        return value

    def to_db_value(self, value: Any, instance: Type[Model] | Model) -> str | None:
        if value is not None:
            value = str(value)
        self.validate(value)
        return value

    class _db_sqlite:
        SQL_TYPE = "VARCHAR(40)"

        def function_cast(self, term: Term) -> Term:
            return functions.Cast(term, SqlTypes.NUMERIC)


class User(Model):
    id = IntField(pk=True)
    money = BigBigIntField(default=10000)


@init_memory_sqlite
async def main() -> None:
    u = await User.create()
    print(u.money)
    a = 9_223_372_036_854_775_807
    u = await User.create(money=a * 10)
    print(u.money)
    print(f"{type(u.money)= }")
    assert u.money == a * 10


if __name__ == "__main__":
    run_async(main())

Pass test with sqlite and mysql.

I'm using Postgresql, is it for it?

@waketzheng
Copy link
Contributor

Sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants