diff --git a/dataloom/columns/__init__.py b/dataloom/columns/__init__.py index 5d1e41f..1936453 100644 --- a/dataloom/columns/__init__.py +++ b/dataloom/columns/__init__.py @@ -14,8 +14,78 @@ class CreatedAtColumn: + """ + CreatedAtColumn + --------------- + + Constructor method for the CreatedAtColumn class. + + Parameters + ---------- + None + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Column : Class for defining regular columns. + PrimaryKeyColumn : Class for defining primary key columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + TableColumn : Class for defining table names in the database. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import CreatedAtColumn, Model, TableColumn + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... createdAt = CreatedAtColumn() + + """ + def __init__(self): - pass + """ + CreatedAtColumn + --------------- + + Constructor method for the CreatedAtColumn class. + + Parameters + ---------- + None + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Column : Class for defining regular columns. + PrimaryKeyColumn : Class for defining primary key columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + TableColumn : Class for defining table names in the database. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import CreatedAtColumn, Model, TableColumn + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... createdAt = CreatedAtColumn() + + """ @property def created_at(self): @@ -25,8 +95,78 @@ def created_at(self): class UpdatedAtColumn: + """ + UpdatedAtColumn + --------------- + + Constructor method for the UpdatedAtColumn class. + + Parameters + ---------- + None + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Column : Class for defining regular columns. + PrimaryKeyColumn : Class for defining primary key columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + TableColumn : Class for defining table names in the database. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import UpdatedAtColumn, Model, TableColumn + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... updatedAt = UpdatedAtColumn() + + """ + def __init__(self): - pass + """ + UpdatedAtColumn + --------------- + + Constructor method for the UpdatedAtColumn class. + + Parameters + ---------- + None + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Column : Class for defining regular columns. + PrimaryKeyColumn : Class for defining primary key columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + TableColumn : Class for defining table names in the database. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import UpdatedAtColumn, Model, TableColumn + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... updatedAt = UpdatedAtColumn() + + """ @property def updated_at(self): @@ -35,12 +175,142 @@ def updated_at(self): ) -@dataclass +@dataclass(kw_only=True, repr=False) class TableColumn: + """ + TableColumn + ----------- + + Constructor method for the TableColumn class. + + Parameters + ---------- + name : str + The name of the table. + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Column : Class for defining regular columns. + PrimaryKeyColumn : Class for defining primary key columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import TableColumn, Model + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + + """ + name: str + def __init__(self, name: str) -> None: + """ + TableColumn + ----------- + + Constructor method for the TableColumn class. + + Parameters + ---------- + name : str + The name of the table. + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Column : Class for defining regular columns. + PrimaryKeyColumn : Class for defining primary key columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import TableColumn, Model + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + + """ + self.name = name + class ForeignKeyColumn: + """ + ForeignKeyColumn + ---------------- + + Constructor method for the ForeignKeyColumn class. + + Parameters + ---------- + table : Model + The referenced model to which the foreign key points. + maps_to : '1-1' | '1-N' | 'N-1' | 'N-N' + The relationship type between the current model and the referenced model. For example, "1-N" for one-to-many. + type : str + The SQL data type for the foreign key column. + required : bool, optional + Indicates whether the foreign key column is required. Default is True. + onDelete : str, optional + The behavior of the foreign key column on deletion of the referenced row. Default is "CASCADE". + onUpdate : str, optional + The behavior of the foreign key column on update of the referenced row. Default is "CASCADE". + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Column : Class for defining regular columns. + PrimaryKeyColumn : Class for defining primary key columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + TableColumn : Class for defining table names in the database. + + Examples + -------- + >>> from dataloom import ForeignKeyColumn, Model, TableColumn + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... createdAt = CreatedAtColumn() + ... updatedAt = UpdatedAtColumn() + ... + ... class Post(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="posts") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... title = Column(type="text", nullable=False) + ... body = Column(type="text", nullable=False) + ... userId = ForeignKeyColumn( + ... User, + ... maps_to="1-1", + ... type="int", + ... required=False, + ... onDelete="CASCADE", + ... onUpdate="CASCADE", + ... ) + + """ + def __init__( self, table, @@ -52,6 +322,67 @@ def __init__( onDelete: CASCADE_LITERAL = "NO ACTION", onUpdate: CASCADE_LITERAL = "NO ACTION", ): + """ + ForeignKeyColumn + ---------------- + + Constructor method for the ForeignKeyColumn class. + + Parameters + ---------- + table : Model + The referenced model to which the foreign key points. + maps_to : '1-1' | '1-N' | 'N-1' | 'N-N' + The relationship type between the current model and the referenced model. For example, "1-N" for one-to-many. + type : str + The SQL data type for the foreign key column. + required : bool, optional + Indicates whether the foreign key column is required. Default is True. + onDelete : str, optional + The behavior of the foreign key column on deletion of the referenced row. Default is "CASCADE". + onUpdate : str, optional + The behavior of the foreign key column on update of the referenced row. Default is "CASCADE". + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Column : Class for defining regular columns. + PrimaryKeyColumn : Class for defining primary key columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + TableColumn : Class for defining table names in the database. + + Examples + -------- + >>> from dataloom import ForeignKeyColumn, Model, TableColumn + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... createdAt = CreatedAtColumn() + ... updatedAt = UpdatedAtColumn() + ... + ... class Post(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="posts") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... title = Column(type="text", nullable=False) + ... body = Column(type="text", nullable=False) + ... userId = ForeignKeyColumn( + ... User, + ... maps_to="1-1", + ... type="int", + ... required=False, + ... onDelete="CASCADE", + ... onUpdate="CASCADE", + ... ) + + """ self.table = table self.required = required self.onDelete = onDelete @@ -108,6 +439,47 @@ def sql_type(self, dialect: DIALECT_LITERAL): class PrimaryKeyColumn: + """ + PrimaryKeyColumn + -------- + + Constructor method for the PrimaryKeyColumn class. + + Parameters + ---------- + type : MYSQL_SQL_TYPES_LITERAL | POSTGRES_SQL_TYPES_LITERAL | SQLITE3_SQL_TYPES_LITERAL + The SQL data type for the column. + length : int | None, optional + The length of the column for data types that require a length parameter. Default is None. + auto_increment : bool, optional + Indicates whether the column is auto-incrementing. Default is False. + nullable : bool, optional + Indicates whether the column can contain null values. Default is False. + unique : bool, optional + Indicates whether the column values must be unique across the table. Default is True. + default : Any | None, optional + The default value for the column. Default is None. + + See Also + -------- + Column : Class for defining regular columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + TableColumn : Class for defining table names in the database. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import PrimaryKeyColumn, Model + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + + """ + def __init__( self, type: MYSQL_SQL_TYPES_LITERAL @@ -119,6 +491,48 @@ def __init__( unique: bool = True, default=None, ): + """ + PrimaryKeyColumn + -------- + + Constructor method for the PrimaryKeyColumn class. + + Parameters + ---------- + type : MYSQL_SQL_TYPES_LITERAL | POSTGRES_SQL_TYPES_LITERAL | SQLITE3_SQL_TYPES_LITERAL + The SQL data type for the column. + length : int | None, optional + The length of the column for data types that require a length parameter. Default is None. + auto_increment : bool, optional + Indicates whether the column is auto-incrementing. Default is False. + nullable : bool, optional + Indicates whether the column can contain null values. Default is False. + unique : bool, optional + Indicates whether the column values must be unique across the table. Default is True. + default : Any | None, optional + The default value for the column. Default is None. + + See Also + -------- + Column : Class for defining regular columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + TableColumn : Class for defining table names in the database. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import PrimaryKeyColumn, Model + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + + + + """ self.type = type self.length = length self.auto_increment = auto_increment @@ -193,6 +607,47 @@ def sql_type(self, dialect: DIALECT_LITERAL): class Column: + """ + Column + ------ + + Constructor method for the Column class. + + Parameters + ---------- + type : MYSQL_SQL_TYPES_LITERAL | POSTGRES_SQL_TYPES_LITERAL + The SQL data type for the column. + nullable : bool, optional + Indicates whether the column can contain null values. Default is True. + unique : bool, optional + Indicates whether the column values must be unique across the table. Default is False. + length : int | None, optional + The length of the column for data types that require a length parameter. Default is None. + auto_increment : bool, optional + Indicates whether the column is auto-incrementing. Default is False. + default : Any | None, optional + The default value for the column. Default is None. + + See Also + -------- + PrimaryKeyColumn : Class for defining primary key columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + TableColumn : Class for defining table names in the database. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import Column, Model + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + + """ + def __init__( self, type: MYSQL_SQL_TYPES_LITERAL @@ -204,6 +659,46 @@ def __init__( auto_increment: bool = False, default=None, ): + """ + Column + ------ + + Constructor method for the Column class. + + Parameters + ---------- + type : MYSQL_SQL_TYPES_LITERAL | POSTGRES_SQL_TYPES_LITERAL + The SQL data type for the column. + nullable : bool, optional + Indicates whether the column can contain null values. Default is True. + unique : bool, optional + Indicates whether the column values must be unique across the table. Default is False. + length : int | None, optional + The length of the column for data types that require a length parameter. Default is None. + auto_increment : bool, optional + Indicates whether the column is auto-incrementing. Default is False. + default : Any | None, optional + The default value for the column. Default is None. + + See Also + -------- + PrimaryKeyColumn : Class for defining primary key columns. + CreatedAtColumn : Class for defining "created_at" timestamp columns. + UpdatedAtColumn : Class for defining "updated_at" timestamp columns. + TableColumn : Class for defining table names in the database. + ForeignKeyColumn : Class for defining foreign key columns. + + Examples + -------- + >>> from dataloom import Column, Model + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type='int', auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + + """ self.type = type self.nullable = nullable self.unique = unique diff --git a/dataloom/keys.py b/dataloom/keys.py index a519747..6129f81 100644 --- a/dataloom/keys.py +++ b/dataloom/keys.py @@ -1,4 +1,4 @@ -push = False +push = True class PgConfig: diff --git a/dataloom/loom/__init__.py b/dataloom/loom/__init__.py index 34beab2..6c36244 100644 --- a/dataloom/loom/__init__.py +++ b/dataloom/loom/__init__.py @@ -28,6 +28,44 @@ class Dataloom(IDataloom): + """ + Dataloom + -------- + + This class allows you to define a loom object for your database connection. + + Parameters + ---------- + database : str + The name of the database to which you will connect, for PostgreSQL or MySQL, and the file name for SQLite. + dialect : "mysql" | "postgres" | "sqlite" + The database dialect to which you want to connect; it is required. + user : str, optional + The database username with which you want to connect. It defaults to the dialect's default values. + host : str, optional + The database host to which you will connect. It defaults to the dialect's default values. + port : int, optional + The database port to which you will connect. It defaults to the dialect's default values. + password : str, optional + The database password for the specified user. It defaults to the dialect's default value. + sql_logger : "console" | "file" + The default logging platform for SQL statements. It defaults to None for no logs on either file or console. + logs_filename : str, optional + The logging file name for SQL statement logs if the sql_logger is set to "file"; otherwise, it defaults to "dataloom.sql". + + Examples + -------- + >>> from dataloom import Dataloom + ... loom = Dataloom( + ... dialect="postgres", + ... database="hi", + ... password="root", + ... user="postgres", + ... sql_logger="console", + ... ) + + """ + def __init__( self, database: str, diff --git a/dataloom/model/__init__.py b/dataloom/model/__init__.py index 1b5e0da..b110ec3 100644 --- a/dataloom/model/__init__.py +++ b/dataloom/model/__init__.py @@ -23,6 +23,32 @@ class Model: + """ + Model + ----- + + A top-level class that all database tables inherit from. + + Attributes + ---------- + __tablename__ : Optional[TableColumn] + The name of the table in the database. If not specified, it defaults to None. + + Examples + -------- + >>> from dataloom import Model, TableColumn, PrimaryKeyColumn, Column + ... from typing import Optional + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type="int", auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + + The above example shows you how you can use the model class to create a table called "users". + + """ + @classmethod def _create_sql(cls, dialect: DIALECT_LITERAL, ignore_exists=True): sqls = GetStatement( diff --git a/dataloom/types/__init__.py b/dataloom/types/__init__.py index ed573d0..92b8112 100644 --- a/dataloom/types/__init__.py +++ b/dataloom/types/__init__.py @@ -31,33 +31,466 @@ @dataclass(kw_only=True, repr=False) class Filter: + """ + Filter + ------ + + Constructor method for the Filter class. + + Parameters + ---------- + column : str + The name of the column to filter on. + operator : "eq" |"neq" |"lt" |"gt" |"leq" |"geq" |"in" |"notIn" |"like" + The operator to use for the filter. + value : Any + The value to compare against. + join_next_filter_with : "AND" | "OR" | None, optional + The SQL operand to join the next filter with. Default is "AND". + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + ColumnValue : Class for defining column values. + Order : Class for defining order specifications. + + Examples + -------- + >>> from dataloom import Filter, ColumnValue, Order, User + ... + ... # Creating a filter for users with id equals 1 or username equals 'miller' + ... affected_rows = loom.update_one( + ... User, + ... filters=[ + ... Filter(column="id", value=1, operator="eq", join_next_filter_with="OR"), + ... Filter(column="username", value="miller"), + ... ], + ... values=[ + ... [ + ... ColumnValue(name="username", value="Mario"), + ... ColumnValue(name="name", value="Mario"), + ... ] + ... ], + ... ) + ... print(affected_rows) + + """ + column: str = field(repr=False) operator: OPERATOR_LITERAL = field(repr=False, default="eq") value: Any = field(repr=False) join_next_filter_with: Optional[SLQ_OPERAND_LITERAL] = field(default="AND") + def __init__( + self, + column: str, + value: Any, + operator: OPERATOR_LITERAL = "eq", + join_next_filter_with: Optional[SLQ_OPERAND_LITERAL] = "AND", + ) -> None: + """ + Filter + ------ + + Constructor method for the Filter class. + + Parameters + ---------- + column : str + The name of the column to filter on. + operator : "eq" |"neq" |"lt" |"gt" |"leq" |"geq" |"in" |"notIn" |"like" + The operator to use for the filter. + value : Any + The value to compare against. + join_next_filter_with : "AND" | "OR" | None, optional + The SQL operand to join the next filter with. Default is "AND". + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + ColumnValue : Class for defining column values. + Order : Class for defining order specifications. + + Examples + -------- + >>> from dataloom import Filter, ColumnValue, Order, User + ... + ... # Creating a filter for users with id equals 1 or username equals 'miller' + ... affected_rows = loom.update_one( + ... User, + ... filters=[ + ... Filter(column="id", value=1, operator="eq", join_next_filter_with="OR"), + ... Filter(column="username", value="miller"), + ... ], + ... values=[ + ... [ + ... ColumnValue(name="username", value="Mario"), + ... ColumnValue(name="name", value="Mario"), + ... ] + ... ], + ... ) + ... print(affected_rows) + + """ + self.column = column + self.value = value + self.join_next_filter_with = join_next_filter_with + self.operator = operator + @dataclass(kw_only=True, repr=False) class ColumnValue[T]: + """ + ColumnValue + ----------- + + Constructor method for the ColumnValue class. + + Parameters + ---------- + name : str + The name of the column. + value : Any + The value to assign to the column. + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Filter : Class for defining filters. + Order : Class for defining order specifications. + + Examples + -------- + >>> from dataloom import ColumnValue, Filter, Order + ... + ... # Model definitions + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type="int", auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... + ... class Post(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="posts") + ... id = PrimaryKeyColumn(type="int", auto_increment=True) + ... title = Column(type="text", nullable=False) + ... content = Column(type="text", nullable=False) + ... userId = ForeignKeyColumn(User, maps_to="1-N", type="int", required=False, onDelete="CASCADE", onUpdate="CASCADE") + ... + ... # Updating the username and name columns for the user with ID 1 + ... affected_rows = loom.update_one( + ... User, + ... filters=Filter(column="id", value=1), + ... values=[ + ... [ + ... ColumnValue(name="username", value="Mario"), + ... ColumnValue(name="name", value="Mario"), + ... ] + ... ], + ... ) + ... print(affected_rows) + + """ + name: str = field(repr=False) value: T = field(repr=False) + def __init__(self, name: str, value: T) -> None: + """ + ColumnValue + ----------- + + Constructor method for the ColumnValue class. + + Parameters + ---------- + name : str + The name of the column. + value : Any + The value to assign to the column. + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Filter : Class for defining filters. + Order : Class for defining order specifications. + + Examples + -------- + >>> from dataloom import ColumnValue, Filter, Order + ... + ... # Model definitions + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type="int", auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... + ... class Post(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="posts") + ... id = PrimaryKeyColumn(type="int", auto_increment=True) + ... title = Column(type="text", nullable=False) + ... content = Column(type="text", nullable=False) + ... userId = ForeignKeyColumn(User, maps_to="1-N", type="int", required=False, onDelete="CASCADE", onUpdate="CASCADE") + ... + ... # Updating the username and name columns for the user with ID 1 + ... affected_rows = loom.update_one( + ... User, + ... filters=Filter(column="id", value=1), + ... values=[ + ... [ + ... ColumnValue(name="username", value="Mario"), + ... ColumnValue(name="name", value="Mario"), + ... ] + ... ], + ... ) + ... print(affected_rows) + + """ + self.name = name + self.value = value + @dataclass(kw_only=True, repr=False) class Order: + """ + Order + ----- + + Constructor method for the Order class. + + Parameters + ---------- + column : str + The name of the column to order by. + order : Literal['ASC', 'DESC'], optional + The order direction. Default is "ASC" (ascending). + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Include : Class for defining included models. + Filter : Class for defining filters. + ColumnValue : Class for defining column values. + + Examples + -------- + >>> from dataloom import Order, Include, Model + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type="int", auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... + ... class Post(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="posts") + ... id = PrimaryKeyColumn(type="int", auto_increment=True) + ... title = Column(type="text", nullable=False) + ... content = Column(type="text", nullable=False) + ... userId = ForeignKeyColumn(User, maps_to="1-N", type="int", required=False, onDelete="CASCADE", onUpdate="CASCADE") + ... + ... # Including posts for a user with ID 1 and ordering by ID in descending order + ... # and then by createdAt in descending order + ... users = loom.find_many( + ... User, + ... pk=1, + ... include=[Include(Post, limit=2, offset=0, maps_to="1-N")], + ... order=[Order(column="id", order="DESC"), Order(column="createdAt", order="DESC")] + ... ) + + """ + column: str = field(repr=False) order: Literal["ASC", "DESC"] = field(repr=False, default="ASC") + def __init__(self, column: str, order: Literal["ASC", "DESC"] = "ASC") -> None: + """ + Order + ----- + + Constructor method for the Order class. + + Parameters + ---------- + column : str + The name of the column to order by. + order : Literal['ASC', 'DESC'], optional + The order direction. Default is "ASC" (ascending). + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Include : Class for defining included models. + Filter : Class for defining filters. + ColumnValue : Class for defining column values. + + Examples + -------- + >>> from dataloom import Order, Include, Model + ... + ... class User(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="users") + ... id = PrimaryKeyColumn(type="int", auto_increment=True) + ... name = Column(type="text", nullable=False) + ... username = Column(type="varchar", unique=True, length=255) + ... + ... class Post(Model): + ... __tablename__: Optional[TableColumn] = TableColumn(name="posts") + ... id = PrimaryKeyColumn(type="int", auto_increment=True) + ... title = Column(type="text", nullable=False) + ... content = Column(type="text", nullable=False) + ... userId = ForeignKeyColumn(User, maps_to="1-N", type="int", required=False, onDelete="CASCADE", onUpdate="CASCADE") + ... + ... # Including posts for a user with ID 1 and ordering by ID in descending order + ... # and then by createdAt in descending order + ... users = loom.find_many( + ... User, + ... pk=1, + ... include=[Include(Post, limit=2, offset=0, maps_to="1-N")], + ... order=[Order(column="id", order="DESC"), Order(column="createdAt", order="DESC")] + ... ) + + """ + self.column = column + self.order = order + @dataclass(kw_only=True, repr=False) class Include[Model]: + """ + Include + ------- + + Constructor method for the Include class. + + Parameters + ---------- + model : Model + The model to be included when eger fetching records. + order : list[Order], optional + The list of order specifications for sorting the included data. Default is an empty list. + limit : int | None, optional + The maximum number of records to include. Default is 0 (no limit). + offset : int | None, optional + The number of records to skip before including. Default is 0 (no offset). + select : list[str] | None, optional + The list of columns to include. Default is None (include all columns). + maps_to : RELATIONSHIP_LITERAL, optional + The relationship type between the current model and the included model. Default is "1-N" (one-to-many). + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Order: Class for defining order specifications. + Filter : Class for defining filters. + ColumnValue : Class for defining column values. + + Examples + -------- + >>> from dataloom import Include, Model, Order + ... + ... # Including posts for a user with ID 1 + ... mysql_loom.find_by_pk( + ... User, pk=1, include=[Include(Post, limit=2, offset=0, select=["id", "title"], maps_to="1-N")] + ... ) + + """ + model: Model = field(repr=False) order: list[Order] = field(repr=False, default_factory=list) - limit: Optional[int] = field(default=None) - offset: Optional[int] = field(default=None) + limit: Optional[int] = field(default=0) + offset: Optional[int] = field(default=0) select: Optional[list[str]] = field(default_factory=list) maps_to: RELATIONSHIP_LITERAL = field(default="1-N") + def __init__( + self, + model: Model, + order: list[Order] = [], + limit: Optional[int] = 0, + offset: Optional[int] = 0, + select: Optional[list[str]] = [], + maps_to: RELATIONSHIP_LITERAL = "1-N", + ): + """ + Include + ------- + + Constructor method for the Include class. + + Parameters + ---------- + model : Model + The model to be included when eger fetching records. + order : list[Order], optional + The list of order specifications for sorting the included data. Default is an empty list. + limit : int | None, optional + The maximum number of records to include. Default is 0 (no limit). + offset : int | None, optional + The number of records to skip before including. Default is 0 (no offset). + select : list[str] | None, optional + The list of columns to include. Default is None (include all columns). + maps_to : RELATIONSHIP_LITERAL, optional + The relationship type between the current model and the included model. Default is "1-N" (one-to-many). + + Returns + ------- + None + This method does not return any value. + + See Also + -------- + Order: Class for defining order specifications. + Filter : Class for defining filters. + ColumnValue : Class for defining column values. + + Examples + -------- + >>> from dataloom import Include, Model, Order + ... + ... # Including posts for a user with ID 1 + ... loom.find_by_pk( + ... User, pk=1, include=[Include(Post, limit=2, offset=0, select=["id", "title"], maps_to="1-N")] + ... ) + + """ + + self.select = select + self.model = model + self.order = order + self.limit = limit + self.offset = offset + self.maps_to = maps_to + POSTGRES_SQL_TYPES = { "int": "INTEGER", diff --git a/hi.db b/hi.db index b731b3a..55e2e0a 100644 Binary files a/hi.db and b/hi.db differ diff --git a/playground.py b/playground.py index 7a3493b..58c8508 100644 --- a/playground.py +++ b/playground.py @@ -9,6 +9,8 @@ ForeignKeyColumn, Filter, ColumnValue, + Include, + Order, ) from typing import Optional @@ -100,6 +102,20 @@ class Category(Model): filters=[Filter(column="id", value=1, operator="eq")], column=ColumnValue(name="tokenVersion", value=2), ) + +affected_rows = mysql_loom.update_one( + User, + filters=[ + Filter(column="id", value=1, operator="eq", join_next_filter_with="OR"), + Filter(column="username", value="miller"), + ], + values=[ + [ + ColumnValue(name="username", value="Mario"), + ColumnValue(name="name", value="Mario"), + ] + ], +) print(affected_rows)