Source code for surrealengine.fields.scalar

import re
from typing import Any, List, Optional, Pattern, Type, Union

from .base import Field

[docs] class StringField(Field): """String field type. This field type stores string values and provides validation for minimum length, maximum length, and regex pattern matching. Attributes: min_length: Minimum length of the string max_length: Maximum length of the string regex: Regular expression pattern to match Examples: Basic string field: >>> name = StringField(required=True) String with length constraints: >>> title = StringField(max_length=100, required=True) >>> username = StringField(min_length=3, max_length=20) String with regex validation: >>> email = StringField(regex=r'^[^@]+@[^@]+\.[^@]+$') >>> slug = StringField(regex=r'^[a-z0-9-]+$') Indexed string field: >>> name = StringField(indexed=True, unique=True) >>> category = StringField(indexed=True) String field with choices: >>> status = StringField(choices=['active', 'inactive', 'pending']) String field for schema definition: >>> name = StringField(required=True, define_schema=True) """
[docs] def __init__(self, min_length: Optional[int] = None, max_length: Optional[int] = None, regex: Optional[str] = None, choices: Optional[list] = None, **kwargs: Any) -> None: """Initialize a new StringField. Args: min_length: Minimum length of the string max_length: Maximum length of the string regex: Regular expression pattern to match choices: List of valid choices for this field required: Whether the field is required (default: False) default: Default value for the field db_field: Name of the field in the database (defaults to the field name) define_schema: Whether to define this field in the schema (even for SCHEMALESS tables) indexed: Whether the field should be indexed (default: False) unique: Whether the index should enforce uniqueness (default: False) search: Whether the index is a search index (default: False) analyzer: Analyzer to use for search indexes index_with: List of other field names to include in the index """ self.min_length = min_length self.max_length = max_length self.regex: Optional[Pattern] = re.compile(regex) if regex else None self.regex_pattern: Optional[str] = regex self.choices: Optional[list] = choices super().__init__(**kwargs) self.py_type = str
[docs] def validate(self, value: Any) -> Optional[str]: """Validate the string value. This method checks if the value is a valid string and meets the constraints for minimum length, maximum length, and regex pattern. Args: value: The value to validate Returns: The validated string value Raises: TypeError: If the value is not a string ValueError: If the value does not meet the constraints """ value = super().validate(value) if value is not None: if not isinstance(value, str): raise TypeError(f"Expected string for field '{self.name}', got {type(value)}") if self.min_length is not None and len(value) < self.min_length: raise ValueError(f"String value for '{self.name}' is too short") if self.max_length is not None and len(value) > self.max_length: raise ValueError(f"String value for '{self.name}' is too long") if self.regex and not self.regex.match(value): raise ValueError(f"String value for '{self.name}' does not match pattern") if self.choices and value not in self.choices: raise ValueError(f"String value for '{self.name}' is not a valid choice") return value
[docs] class NumberField(Field): """Base class for numeric fields. This field type is the base class for all numeric field types. It provides validation for minimum and maximum values. Attributes: min_value: Minimum allowed value max_value: Maximum allowed value Examples: Basic number field: >>> score = NumberField() Number with range constraints: >>> priority = NumberField(min_value=1, max_value=5, default=3) >>> percentage = NumberField(min_value=0, max_value=100) >>> age = NumberField(min_value=0) Required number field: >>> price = NumberField(min_value=0, required=True) """
[docs] def __init__(self, min_value: Optional[Union[int, float]] = None, max_value: Optional[Union[int, float]] = None, **kwargs: Any) -> None: """Initialize a new NumberField. Args: min_value: Minimum allowed value max_value: Maximum allowed value required: Whether the field is required (default: False) default: Default value for the field db_field: Name of the field in the database (defaults to the field name) define_schema: Whether to define this field in the schema (even for SCHEMALESS tables) indexed: Whether the field should be indexed (default: False) unique: Whether the index should enforce uniqueness (default: False) search: Whether the index is a search index (default: False) analyzer: Analyzer to use for search indexes index_with: List of other field names to include in the index """ self.min_value = min_value self.max_value = max_value super().__init__(**kwargs) self.py_type = Union[int, float]
[docs] def validate(self, value: Any) -> Optional[Union[int, float]]: """Validate the numeric value. This method checks if the value is a valid number and meets the constraints for minimum and maximum values. Args: value: The value to validate Returns: The validated numeric value Raises: TypeError: If the value is not a number ValueError: If the value does not meet the constraints """ value = super().validate(value) if value is not None: from decimal import Decimal if not isinstance(value, (int, float, Decimal)): raise TypeError(f"Expected number for field '{self.name}', got {type(value)}") if self.min_value is not None and value < self.min_value: raise ValueError(f"Value for '{self.name}' is too small") if self.max_value is not None and value > self.max_value: raise ValueError(f"Value for '{self.name}' is too large") return value
[docs] class IntField(NumberField): """Integer field type. This field type stores integer values and provides validation to ensure the value is an integer. Examples: Basic integer field: >>> age = IntField(min_value=0) >>> count = IntField(default=0) Integer with constraints: >>> priority = IntField(min_value=1, max_value=5, default=3) >>> year = IntField(min_value=1900, max_value=2100) Required integer: >>> user_id = IntField(required=True) >>> views = IntField(default=0, min_value=0) """
[docs] def __init__(self, **kwargs: Any) -> None: """Initialize a new IntField. Args: min_value: Minimum allowed value max_value: Maximum allowed value required: Whether the field is required (default: False) default: Default value for the field db_field: Name of the field in the database (defaults to the field name) define_schema: Whether to define this field in the schema (even for SCHEMALESS tables) indexed: Whether the field should be indexed (default: False) unique: Whether the index should enforce uniqueness (default: False) search: Whether the index is a search index (default: False) analyzer: Analyzer to use for search indexes index_with: List of other field names to include in the index """ super().__init__(**kwargs) self.py_type = int
[docs] def validate(self, value: Any) -> Optional[int]: """Validate the integer value. This method checks if the value is a valid integer. Args: value: The value to validate Returns: The validated integer value Raises: TypeError: If the value is not an integer """ value = super().validate(value) if value is not None and not isinstance(value, int): raise TypeError(f"Expected integer for field '{self.name}', got {type(value)}") return value
[docs] def to_db(self, value: Any) -> Optional[int]: """Convert Python value to database representation. This method converts a Python value to an integer for storage in the database. Args: value: The Python value to convert Returns: The integer value for the database """ if value is not None: return int(value) return value
[docs] class FloatField(NumberField): """Float field type. This field type stores floating-point values and provides validation to ensure the value can be converted to a float. Examples: Basic float field: >>> price = FloatField(min_value=0) >>> rating = FloatField(min_value=0.0, max_value=5.0) Float with precision: >>> estimated_hours = FloatField(min_value=0.1) >>> percentage = FloatField(min_value=0.0, max_value=100.0) Financial data: >>> balance = FloatField(default=0.0) >>> tax_rate = FloatField(min_value=0.0, max_value=1.0) """
[docs] def __init__(self, **kwargs: Any) -> None: """Initialize a new FloatField. Args: min_value: Minimum allowed value max_value: Maximum allowed value required: Whether the field is required (default: False) default: Default value for the field db_field: Name of the field in the database (defaults to the field name) define_schema: Whether to define this field in the schema (even for SCHEMALESS tables) indexed: Whether the field should be indexed (default: False) unique: Whether the index should enforce uniqueness (default: False) search: Whether the index is a search index (default: False) analyzer: Analyzer to use for search indexes index_with: List of other field names to include in the index """ super().__init__(**kwargs) self.py_type = float
[docs] def validate(self, value: Any) -> Optional[float]: """Validate the float value. This method checks if the value can be converted to a float. Args: value: The value to validate Returns: The validated float value Raises: TypeError: If the value cannot be converted to a float """ value = super().validate(value) if value is not None: try: return float(value) except (TypeError, ValueError): raise TypeError(f"Expected float for field '{self.name}', got {type(value)}") return value
[docs] class BooleanField(Field): """Boolean field type. This field type stores boolean values and provides validation to ensure the value is a boolean. Examples: Basic boolean field: >>> active = BooleanField(default=True) >>> completed = BooleanField(default=False) Required boolean: >>> is_primary_author = BooleanField(default=True) >>> published = BooleanField(default=False) Boolean with indexing: >>> active = BooleanField(default=True, indexed=True) """
[docs] def __init__(self, **kwargs: Any) -> None: """Initialize a new BooleanField. Args: required: Whether the field is required (default: False) default: Default value for the field db_field: Name of the field in the database (defaults to the field name) define_schema: Whether to define this field in the schema (even for SCHEMALESS tables) indexed: Whether the field should be indexed (default: False) unique: Whether the index should enforce uniqueness (default: False) search: Whether the index is a search index (default: False) analyzer: Analyzer to use for search indexes index_with: List of other field names to include in the index """ super().__init__(**kwargs) self.py_type = bool
[docs] def validate(self, value: Any) -> Optional[bool]: """Validate the boolean value. This method checks if the value is a valid boolean. Args: value: The value to validate Returns: The validated boolean value Raises: TypeError: If the value is not a boolean """ value = super().validate(value) if value is not None and not isinstance(value, bool): raise TypeError(f"Expected boolean for field '{self.name}', got {type(value)}") return value