From 7baaee63ce4753198956e9cbcc6f7019bbcf7b79 Mon Sep 17 00:00:00 2001 From: xiechen Date: Fri, 6 Aug 2021 11:43:51 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9ASmallInteger()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- docs/api/fields/model-fields.md | 28 ++++++ docs/fields/field-types.md | 13 +++ docs/index.md | 1 + ormar/__init__.py | 2 + ormar/fields/__init__.py | 2 + ormar/fields/model_fields.py | 96 +++++++++---------- .../test_encryption/test_encrypted_columns.py | 1 + tests/test_fastapi/test_choices_schema.py | 1 + .../test_model_definition.py | 1 + 10 files changed, 98 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 82f42d9..9b2523d 100644 --- a/README.md +++ b/README.md @@ -614,8 +614,8 @@ Available Model Fields (with required args - optional ones in docs): * `Time()` * `DateTime()` * `JSON()` -* `SmallInteger()` * `BigInteger()` +* `SmallInteger()` * `Decimal(scale, precision)` * `UUID()` * `LargeBinary(max_length)` diff --git a/docs/api/fields/model-fields.md b/docs/api/fields/model-fields.md index 3d4162b..adbf405 100644 --- a/docs/api/fields/model-fields.md +++ b/docs/api/fields/model-fields.md @@ -347,6 +347,34 @@ Accepts required and optional parameters that each column type accepts. `sqlalchemy Column`: initialized column with proper options + +## SmallInteger Objects + +```python +class SmallInteger(Integer, int) +``` + +SmallInteger field factory that construct Field classes and populated their values. + + +#### get\_column\_type + +```python + | @classmethod + | get_column_type(cls, **kwargs: Any) -> Any +``` + +Return proper type of db column for given field type. +Accepts required and optional parameters that each column type accepts. + +**Arguments**: + +- `kwargs` (`Any`): key, value pairs of sqlalchemy options + +**Returns**: + +`sqlalchemy Column`: initialized column with proper options + ## Decimal Objects diff --git a/docs/fields/field-types.md b/docs/fields/field-types.md index 12b703b..b76e288 100644 --- a/docs/fields/field-types.md +++ b/docs/fields/field-types.md @@ -69,6 +69,19 @@ Each of the `Fields` has assigned both `sqlalchemy` column class and python type !!!tip For explanation of other parameters check [pydantic][pydantic] documentation. +### SmallInteger + +`SmallInteger(minimum: int = None, + maximum: int = None, + multiple_of: int = None)` has no required parameters. + +* Sqlalchemy column: `sqlalchemy.SmallInteger` +* Type (used for pydantic): `int` + +!!!tip + For explanation of other parameters check [pydantic][pydantic] documentation. + + ### Float `Float(minimum: float = None, diff --git a/docs/index.md b/docs/index.md index c215fe5..20f8c86 100644 --- a/docs/index.md +++ b/docs/index.md @@ -636,6 +636,7 @@ Available Model Fields (with required args - optional ones in docs): * `DateTime()` * `JSON()` * `BigInteger()` +* `SmallInteger()` * `Decimal(scale, precision)` * `UUID()` * `LargeBinary(max_length)` diff --git a/ormar/__init__.py b/ormar/__init__.py index c9f8bc8..1c71fa9 100644 --- a/ormar/__init__.py +++ b/ormar/__init__.py @@ -41,6 +41,7 @@ from ormar.exceptions import ( # noqa: I100 from ormar.fields import ( BaseField, BigInteger, + SmallInteger, Boolean, DECODERS_MAP, Date, @@ -80,6 +81,7 @@ __version__ = "0.10.15" __all__ = [ "Integer", "BigInteger", + "SmallInteger", "Boolean", "Time", "Text", diff --git a/ormar/fields/__init__.py b/ormar/fields/__init__.py index bc679c4..9745b1b 100644 --- a/ormar/fields/__init__.py +++ b/ormar/fields/__init__.py @@ -9,6 +9,7 @@ from ormar.fields.foreign_key import ForeignKey, ForeignKeyField, UniqueColumns from ormar.fields.many_to_many import ManyToMany, ManyToManyField from ormar.fields.model_fields import ( BigInteger, + SmallInteger, Boolean, Date, DateTime, @@ -29,6 +30,7 @@ from ormar.fields.through_field import Through, ThroughField __all__ = [ "Decimal", "BigInteger", + "SmallInteger", "Boolean", "Date", "DateTime", diff --git a/ormar/fields/model_fields.py b/ormar/fields/model_fields.py index 1196048..a53ac0e 100644 --- a/ormar/fields/model_fields.py +++ b/ormar/fields/model_fields.py @@ -538,54 +538,6 @@ else: ) -class SmallInteger(Integer, int): - """ - SmallInteger field factory that construct Field classes and populated their values. - """ - - _type = int - _sample = 0 - - def __new__( # type: ignore - cls, - *, - minimum: int = None, - maximum: int = None, - multiple_of: int = None, - **kwargs: Any - ) -> BaseField: - autoincrement = kwargs.pop("autoincrement", None) - autoincrement = ( - autoincrement - if autoincrement is not None - else kwargs.get("primary_key", False) - ) - kwargs = { - **kwargs, - **{ - k: v - for k, v in locals().items() - if k not in ["cls", "__class__", "kwargs"] - }, - } - kwargs["ge"] = kwargs["minimum"] - kwargs["le"] = kwargs["maximum"] - return super().__new__(cls, **kwargs) - - @classmethod - def get_column_type(cls, **kwargs: Any) -> Any: - """ - Return proper type of db column for given field type. - Accepts required and optional parameters that each column type accepts. - - :param kwargs: key, value pairs of sqlalchemy options - :type kwargs: Any - :return: initialized column with proper options - :rtype: sqlalchemy Column - """ - return sqlalchemy.SmallInteger() - - class BigInteger(Integer, int): """ BigInteger field factory that construct Field classes and populated their values. @@ -634,6 +586,54 @@ class BigInteger(Integer, int): return sqlalchemy.BigInteger() +class SmallInteger(Integer, int): + """ + SmallInteger field factory that construct Field classes and populated their values. + """ + + _type = int + _sample = 0 + + def __new__( # type: ignore + cls, + *, + minimum: int = None, + maximum: int = None, + multiple_of: int = None, + **kwargs: Any + ) -> BaseField: + autoincrement = kwargs.pop("autoincrement", None) + autoincrement = ( + autoincrement + if autoincrement is not None + else kwargs.get("primary_key", False) + ) + kwargs = { + **kwargs, + **{ + k: v + for k, v in locals().items() + if k not in ["cls", "__class__", "kwargs"] + }, + } + kwargs["ge"] = kwargs["minimum"] + kwargs["le"] = kwargs["maximum"] + return super().__new__(cls, **kwargs) + + @classmethod + def get_column_type(cls, **kwargs: Any) -> Any: + """ + Return proper type of db column for given field type. + Accepts required and optional parameters that each column type accepts. + + :param kwargs: key, value pairs of sqlalchemy options + :type kwargs: Any + :return: initialized column with proper options + :rtype: sqlalchemy Column + """ + return sqlalchemy.SmallInteger() + + class Decimal(ModelFieldFactory, decimal.Decimal): """ Decimal field factory that construct Field classes and populated their values. diff --git a/tests/test_encryption/test_encrypted_columns.py b/tests/test_encryption/test_encrypted_columns.py index 2cfe0e8..504e2b2 100644 --- a/tests/test_encryption/test_encrypted_columns.py +++ b/tests/test_encryption/test_encrypted_columns.py @@ -67,6 +67,7 @@ class Author(ormar.Model): test_time = ormar.Time(default=datetime.time, **default_fernet) test_json = ormar.JSON(default={}, **default_fernet) test_bigint: int = ormar.BigInteger(default=0, **default_fernet) + test_smallint: int = ormar.SmallInteger(default=0, **default_fernet) test_decimal = ormar.Decimal(scale=2, precision=10, **default_fernet) test_decimal2 = ormar.Decimal(max_digits=10, decimal_places=2, **default_fernet) custom_backend: str = ormar.String( diff --git a/tests/test_fastapi/test_choices_schema.py b/tests/test_fastapi/test_choices_schema.py index 6d87fa4..cb93f62 100644 --- a/tests/test_fastapi/test_choices_schema.py +++ b/tests/test_fastapi/test_choices_schema.py @@ -42,6 +42,7 @@ class Organisation(ormar.Model): ident: str = ormar.String(max_length=100, choices=["ACME Ltd", "Other ltd"]) priority: int = ormar.Integer(choices=[1, 2, 3, 4, 5]) priority2: int = ormar.BigInteger(choices=[1, 2, 3, 4, 5]) + priority3: int = ormar.SmallInteger(choices=[1, 2, 3, 4, 5]) expire_date: datetime.date = ormar.Date( choices=[datetime.date(2021, 1, 1), datetime.date(2022, 5, 1)] ) diff --git a/tests/test_model_definition/test_model_definition.py b/tests/test_model_definition/test_model_definition.py index 399d8e8..9bacfce 100644 --- a/tests/test_model_definition/test_model_definition.py +++ b/tests/test_model_definition/test_model_definition.py @@ -35,6 +35,7 @@ class ExampleModel(Model): test_time = ormar.Time(default=datetime.time) test_json = ormar.JSON(default={}) test_bigint: int = ormar.BigInteger(default=0) + test_smallint: int = ormar.SmallInteger(default=0) test_decimal = ormar.Decimal(scale=2, precision=10) test_decimal2 = ormar.Decimal(max_digits=10, decimal_places=2)