Skip to content

Commit

Permalink
delete with filters and som docs
Browse files Browse the repository at this point in the history
  • Loading branch information
CrispenGari committed Feb 8, 2024
1 parent 4b6f4d1 commit 31d722a
Show file tree
Hide file tree
Showing 16 changed files with 1,193 additions and 22,886 deletions.
382 changes: 300 additions & 82 deletions README.md

Large diffs are not rendered by default.

22,070 changes: 12 additions & 22,058 deletions dataloom.sql

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions dataloom/columns/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
SQLITE3_SQL_TYPES_LITERAL,
CASCADE_LITERAL,
DIALECT_LITERAL,
RELATIONSHIP_LITERAL,
)
from dataclasses import dataclass
from dataloom.exceptions import UnsupportedTypeException, UnsupportedDialectException
Expand Down Expand Up @@ -46,6 +47,7 @@ def __init__(
type: MYSQL_SQL_TYPES_LITERAL
| POSTGRES_SQL_TYPES_LITERAL
| SQLITE3_SQL_TYPES_LITERAL,
maps_to: RELATIONSHIP_LITERAL = "1-N",
required: bool = True,
onDelete: CASCADE_LITERAL = "NO ACTION",
onUpdate: CASCADE_LITERAL = "NO ACTION",
Expand All @@ -55,6 +57,7 @@ def __init__(
self.onDelete = onDelete
self.onUpdate = onUpdate
self.type = type
self.maps_to = maps_to

def sql_type(self, dialect: DIALECT_LITERAL):
if dialect == "postgres":
Expand Down
4 changes: 4 additions & 0 deletions dataloom/exceptions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ class PkNotDefinedException(Exception):
pass


class InvalidArgumentsException(Exception):
pass


class TooManyPkException(Exception):
pass

Expand Down
87 changes: 65 additions & 22 deletions dataloom/loom/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import psycopg2
from mysql import connector

import sqlite3
from dataloom.constants import instances

from dataloom.exceptions import (
UnsupportedDialectException,
InvalidColumnValuesException,
InvalidArgumentsException,
)

from dataloom.model import Model
from dataloom.statements import GetStatement
from dataloom.conn import ConnectionOptionsFactory
Expand Down Expand Up @@ -114,9 +117,9 @@ def _execute_sql(
result = cursor.rowcount
else:
if fetchmany:
result = cursor.fetchmany()
result = [res for res in cursor.fetchmany()]
elif fetchall:
result = cursor.fetchall()
result = [res for res in cursor.fetchall()]
elif fetchone:
result = cursor.fetchone()
else:
Expand Down Expand Up @@ -244,13 +247,15 @@ def connect_and_sync(
for model in models:
if drop or force:
self._execute_sql(model._drop_sql(dialect=self.dialect))
self._execute_sql(model._create_sql(dialect=self.dialect))
for sql in model._create_sql(dialect=self.dialect):
if sql is not None:
self._execute_sql(sql)
elif alter:
pass
else:
self._execute_sql(
model._create_sql(dialect=self.dialect, ignore_exists=True)
)
for sql in model._create_sql(dialect=self.dialect):
if sql is not None:
self._execute_sql(sql)
return self.conn, self.tables
except Exception as e:
raise Exception(e)
Expand All @@ -260,13 +265,15 @@ def sync(self, models: list[Model], drop=False, force=False, alter=False):
for model in models:
if drop or force:
self._execute_sql(model._drop_sql(dialect=self.dialect))
self._execute_sql(model._create_sql(dialect=self.dialect))
for sql in model._create_sql(dialect=self.dialect):
if sql is not None:
self._execute_sql(sql)
elif alter:
pass
else:
self._execute_sql(
model._create_sql(dialect=self.dialect, ignore_exists=True)
)
for sql in model._create_sql(dialect=self.dialect):
if sql is not None:
self._execute_sql(sql)
return self.tables
except Exception as e:
raise Exception(e)
Expand Down Expand Up @@ -330,6 +337,8 @@ def find_many(
offset: Optional[int] = None,
order: Optional[list[Order]] = [],
) -> list:
return_dict = True
include = []
sql, params, fields = instance._get_select_where_stm(
dialect=self.dialect,
filters=filters,
Expand Down Expand Up @@ -363,6 +372,7 @@ def find_all(
order: Optional[list[Order]] = [],
) -> list:
return_dict = True
include = []
sql, params, fields = instance._get_select_where_stm(
dialect=self.dialect,
select=select,
Expand All @@ -389,7 +399,7 @@ def __map_relationships(
instance: Model,
row: tuple,
parent_fields: list,
include: list[Include] = [],
include: list[dict] = [],
return_dict: bool = True,
):
# how are relations are mapped?
Expand All @@ -414,19 +424,23 @@ def find_by_pk(
include: list[Include] = [],
return_dict: bool = True,
):
# """
# This part will be added in the future version.
# """
return_dict = True
include = []
# what is the name of the primary key column? well we will find out
sql, fields = instance._get_select_by_pk_stm(
sql, fields, _includes = instance._get_select_by_pk_stm(
dialect=self.dialect, select=select, include=include
)
row = self._execute_sql(sql, args=(pk,), fetchone=True)
if row is None:
rows = self._execute_sql(sql, args=(pk,), fetchone=True)
if rows is None:
return None
return self.__map_relationships(
instance=instance,
row=row,
row=rows,
parent_fields=fields,
include=include,
include=_includes,
return_dict=return_dict,
)

Expand All @@ -440,6 +454,7 @@ def find_one(
offset: Optional[int] = None,
):
return_dict = True
include = []
sql, params, fields = instance._get_select_where_stm(
dialect=self.dialect,
filters=filters,
Expand Down Expand Up @@ -500,24 +515,49 @@ def delete_by_pk(self, instance: Model, pk):
return affected_rows

def delete_one(
self, instance: Model, filters: Optional[Filter | list[Filter]] = None
self,
instance: Model,
filters: Optional[Filter | list[Filter]] = None,
offset: Optional[int] = None,
order: Optional[list[Order]] = [],
):
sql, params = instance._get_delete_where_stm(
dialect=self.dialect,
filters=filters,
dialect=self.dialect, filters=filters, offset=offset, order=order
)
affected_rows = self._execute_sql(sql, args=params, affected_rows=True)
args = [*params]
if offset is not None:
args.append(offset)
affected_rows = self._execute_sql(sql, args=args, affected_rows=True)
return affected_rows

def delete_bulk(
self, instance: Model, filters: Optional[Filter | list[Filter]] = None
self,
instance: Model,
filters: Optional[Filter | list[Filter]] = None,
limit: Optional[int] = None,
offset: Optional[int] = None,
order: Optional[list[Order]] = [],
):
if offset is not None and limit is None and self.dialect == "mysql":
raise InvalidArgumentsException(
f"You can not apply offset without limit on dialect '{self.dialect}'."
)
sql, params = instance._get_delete_bulk_where_stm(
dialect=self.dialect,
filters=filters,
offset=offset,
limit=limit,
order=order,
)
args = [*params]

if limit is not None:
args.append(limit)
if offset is not None:
args.append(offset)

affected_rows = self._execute_sql(
sql, args=params, affected_rows=True, fetchall=True
sql, args=args, affected_rows=True, fetchall=True
)
return affected_rows

Expand Down Expand Up @@ -562,3 +602,6 @@ def decrement(
args = [*column_values, *filter_values]
affected_rows = self._execute_sql(sql, args=args, affected_rows=True)
return affected_rows

def inspect(self):
pass
68 changes: 57 additions & 11 deletions dataloom/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ class Model:

@classmethod
def _create_sql(cls, dialect: DIALECT_LITERAL, ignore_exists=True):
sql = GetStatement(
sqls = GetStatement(
dialect=dialect, model=cls, table_name=cls._get_table_name()
)._get_create_table_command
return sql
return sqls

@classmethod
def _get_table_name(self):
Expand Down Expand Up @@ -124,7 +124,7 @@ def _get_select_where_stm(
order: Optional[list[Order]] = [],
include: list[Include] = [],
):
orders = list()
orders = []
includes = []
# what are the foreign keys?

Expand Down Expand Up @@ -227,7 +227,7 @@ def _get_select_by_pk_stm(
raise UnsupportedDialectException(
"The dialect passed is not supported the supported dialects are: {'postgres', 'mysql', 'sqlite'}"
)
return sql, fields if len(select) == 0 else select
return sql, fields if len(select) == 0 else select, includes

@classmethod
def _get_update_by_pk_stm(
Expand Down Expand Up @@ -373,7 +373,11 @@ def _get_delete_by_pk_stm(cls, dialect: DIALECT_LITERAL):

@classmethod
def _get_delete_where_stm(
cls, dialect: DIALECT_LITERAL, filters: Optional[Filter | list[Filter]] = None
cls,
dialect: DIALECT_LITERAL,
filters: Optional[Filter | list[Filter]] = None,
offset: Optional[int] = None,
order: Optional[list[Order]] = [],
):
fields, pk_name, fks, updatedAtColumName = get_table_fields(
cls, dialect=dialect
Expand All @@ -384,17 +388,34 @@ def _get_delete_where_stm(
fields=fields,
filters=filters,
)

orders = []
for _order in order:
if _order.column not in fields:
raise UnknownColumnException(
f'The table "{cls._get_table_name()}" does not have a column "{_order.column}".'
)
orders.append(
f'"{_order.column}" {_order.order}'
if dialect == "postgres"
else f"`{_order.column}` {_order.order}"
)
if dialect == "postgres" or "mysql" or "sqlite":
if len(placeholder_filters) == 0:
sql = GetStatement(
dialect=dialect, model=cls, table_name=cls._get_table_name()
)._get_delete_first_command(pk_name=pk_name)
)._get_delete_first_command(
pk_name=pk_name,
offset=offset,
orders=orders,
)
else:
sql = GetStatement(
dialect=dialect, model=cls, table_name=cls._get_table_name()
)._get_delete_one_where_command(
pk_name=pk_name, filters=placeholder_filters
pk_name=pk_name,
filters=placeholder_filters,
offset=offset,
orders=orders,
)
else:
raise UnsupportedDialectException(
Expand All @@ -404,7 +425,12 @@ def _get_delete_where_stm(

@classmethod
def _get_delete_bulk_where_stm(
cls, dialect: DIALECT_LITERAL, filters: Optional[Filter | list[Filter]] = None
cls,
dialect: DIALECT_LITERAL,
filters: Optional[Filter | list[Filter]] = None,
limit: Optional[int] = None,
offset: Optional[int] = None,
order: Optional[list[Order]] = [],
):
fields, pk_name, fks, updatedAtColumName = get_table_fields(
cls, dialect=dialect
Expand All @@ -415,15 +441,35 @@ def _get_delete_bulk_where_stm(
fields=fields,
filters=filters,
)

orders = []
for _order in order:
if _order.column not in fields:
raise UnknownColumnException(
f'The table "{cls._get_table_name()}" does not have a column "{_order.column}".'
)
orders.append(
f'"{_order.column}" {_order.order}'
if dialect == "postgres"
else f"`{_order.column}` {_order.order}"
)
if dialect == "postgres" or "mysql" or "sqlite":
if len(placeholder_filters) == 0:
sql = GetStatement(
dialect=dialect, model=cls, table_name=cls._get_table_name()
)._get_delete_all_command()
)._get_delete_all_command(
pk_name=pk_name, offset=offset, limit=limit, orders=orders
)
else:
sql = GetStatement(
dialect=dialect, model=cls, table_name=cls._get_table_name()
)._get_delete_bulk_where_command(filters=placeholder_filters)
)._get_delete_bulk_where_command(
filters=placeholder_filters,
pk_name=pk_name,
offset=offset,
limit=limit,
orders=orders,
)
else:
raise UnsupportedDialectException(
"The dialect passed is not supported the supported dialects are: {'postgres', 'mysql', 'sqlite'}"
Expand Down
Loading

0 comments on commit 31d722a

Please sign in to comment.