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

Remove dead code 2 (the code strikes back) #3975

Merged
merged 73 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
15713fa
move DataFile model to non-deprecated namespace
mathemancer Oct 15, 2024
270db1e
remove shared object models
mathemancer Oct 15, 2024
72af0af
remove deprecated Exploration model
mathemancer Oct 15, 2024
96acad9
remove unused validators
mathemancer Oct 15, 2024
2cd551b
remove unused Permissions Role models
mathemancer Oct 15, 2024
e5c43f2
remove tests for unused import types
mathemancer Oct 15, 2024
8ce26bd
add migrations for removed permissions role models
mathemancer Oct 15, 2024
8cfdee6
remove deprecated model usage in remaining tests
mathemancer Oct 15, 2024
7fb8613
remove deprecated model use from migrations, signals
mathemancer Oct 15, 2024
6d280fd
remove unused import function
mathemancer Oct 15, 2024
23b0195
remove deprecated model use from remaining exception class
mathemancer Oct 15, 2024
e2cc891
add forgotten migration
mathemancer Oct 15, 2024
8ffe233
remove mathesar state wrangling functions
mathemancer Oct 15, 2024
a089885
remove unused imports
mathemancer Oct 15, 2024
7daaf8e
remove remaining import of deprecated models
mathemancer Oct 15, 2024
9b5c56d
remove all deprecated models, reset migrations
mathemancer Oct 15, 2024
48d03aa
remove unused import module
mathemancer Oct 15, 2024
c813831
Merge branch 'develop' into remove_dead_code_2
mathemancer Oct 16, 2024
ba7f2ab
remove engine usage from import modules
mathemancer Oct 16, 2024
c708147
remove old engine creator
mathemancer Oct 16, 2024
c8b1fbe
remove unused Relation model base
mathemancer Oct 16, 2024
67b2b2f
remove metadata cache function
mathemancer Oct 16, 2024
194341d
remove unused testing cruft
mathemancer Oct 16, 2024
69a43db
remove unused test data files
mathemancer Oct 16, 2024
8b63ec6
remove unused utility modules
mathemancer Oct 16, 2024
c82bbe2
clean up unused imports
mathemancer Oct 16, 2024
a072b43
fix import_ import
mathemancer Oct 16, 2024
dfb2f8b
remove unused table alter functions
mathemancer Oct 16, 2024
14b890f
remove unused table merging function
mathemancer Oct 16, 2024
73c96c2
remove tests for unused functionality
mathemancer Oct 16, 2024
3c4ef3d
remove python-layer type inference
mathemancer Oct 16, 2024
87c1ddc
remove unused imports
mathemancer Oct 16, 2024
36f580b
remove unused SQLAlchemy table creators
mathemancer Oct 16, 2024
acea97e
remove unused SQLAlchemy table dropper
mathemancer Oct 16, 2024
d0440f1
remove unused SQLAlchemy column moving function
mathemancer Oct 16, 2024
54ad8e6
remove unused column extraction function
mathemancer Oct 16, 2024
5d0c176
remove unused SQLAlchemy column deletion functions
mathemancer Oct 16, 2024
ed6f39a
remove unused SQLAlchemy record insert functions
mathemancer Oct 16, 2024
564e4b7
remove unused record search transform
mathemancer Oct 16, 2024
3164a6f
remove unused SQLAlchemy record update function
mathemancer Oct 16, 2024
d8f83a4
remove some schema utils
mathemancer Oct 16, 2024
2218d5f
remove first layer of schema functions
mathemancer Oct 16, 2024
56e5f43
move schema funcs only used in testing to conftest
mathemancer Oct 16, 2024
425d692
remove unused dependents code
mathemancer Oct 16, 2024
5a471d2
remove unused constraint code
mathemancer Oct 16, 2024
f125eda
remove unused SQLAlchemy-based link functions
mathemancer Oct 16, 2024
522dc39
remove obsolete cast function testing
mathemancer Oct 16, 2024
12a82bc
remove unused col alter functions
mathemancer Oct 16, 2024
d392aba
remove unused SQLAlchemy-based column create functions
mathemancer Oct 16, 2024
15aaa5c
remove unused SQLAlchemy-based column functions
mathemancer Oct 16, 2024
7322aea
remove unused column utilites functions
mathemancer Oct 16, 2024
b2a325b
remove unneeded MathesarColumn properties
mathemancer Oct 17, 2024
025ff72
remove unused SA type code
mathemancer Oct 17, 2024
e8fce62
remove unused column testing utils
mathemancer Oct 17, 2024
a411e25
remove unused code from module
mathemancer Oct 17, 2024
79cee72
remove unused attributes of ExplorationResult type
mathemancer Oct 18, 2024
97e1d08
remove unused record processing
mathemancer Oct 18, 2024
585bb10
remove unused Group and DuplicatesOnly transforms
mathemancer Oct 18, 2024
5dc247e
move into DBQuery object
mathemancer Oct 18, 2024
69b2c92
remove unused record grouping code
mathemancer Oct 18, 2024
c0f3a0a
remove record calculation module, related tests
mathemancer Oct 18, 2024
47bab20
remove SQLAlchemy column alterer
mathemancer Oct 18, 2024
ad6ca2e
deal with and update TODOs in db module
mathemancer Oct 18, 2024
34e2f53
remove unneeded code from db.types.base
mathemancer Oct 18, 2024
ad651b6
remove SQLAlchemy get_joinable_tables function
mathemancer Oct 18, 2024
8b68d0e
remove get_oid_from_table function
mathemancer Oct 18, 2024
50bd82f
clean up and remove unneeded tests
mathemancer Oct 18, 2024
c10c8ce
remove unneeded connection functions
mathemancer Oct 18, 2024
e482b6e
remove unneeded utilities and constants
mathemancer Oct 18, 2024
e994aae
remove unused utility function
mathemancer Oct 18, 2024
e48438b
Merge branch 'develop' into remove_dead_code_2
mathemancer Oct 18, 2024
f3e7f41
remove unused imports
mathemancer Oct 18, 2024
5f4fd63
Merge branch 'develop' into remove_dead_code_2
Anish9901 Oct 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 66 additions & 84 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@
# These imports come from the mathesar namespace, because our DB setup logic depends on it.
from django.db import connection as dj_connection

from sqlalchemy import MetaData, text, Table
from sqlalchemy import MetaData, text, Table, select, or_
from sqlalchemy.exc import OperationalError
from sqlalchemy_utils import database_exists, create_database, drop_database

from db.engine import add_custom_types_to_ischema_names, create_engine as sa_create_engine
from db.sql import install as sql_install
from db.schemas.operations.drop import drop_schema_via_name as drop_sa_schema
from db.schemas.operations.create import create_schema_if_not_exists_via_sql_alchemy
from db.schemas.utils import get_schema_oid_from_name, get_schema_name_from_oid
from db.utils import get_pg_catalog_table
from db.metadata import get_empty_metadata

from fixtures.utils import create_scoped_fixtures

Expand Down Expand Up @@ -162,28 +161,6 @@ def _test_schema_name():
return "_test_schema_name"


# TODO does testing this make sense?
@pytest.fixture(scope="module")
def engine_without_ischema_names_updated(test_db_name, MOD_engine_cache):
"""
For testing environments where an engine might not be fully setup.

We instantiate a new engine cache, without updating its ischema_names dict.
"""
return MOD_engine_cache(test_db_name)


# TODO seems unneeded: remove
@pytest.fixture
def engine_with_schema_without_ischema_names_updated(
engine_without_ischema_names_updated, _test_schema_name, create_db_schema
):
engine = engine_without_ischema_names_updated
schema_name = _test_schema_name
create_db_schema(schema_name, engine)
return engine, schema_name


@pytest.fixture
def engine_with_schema(engine, _test_schema_name, create_db_schema):
schema_name = _test_schema_name
Expand All @@ -210,8 +187,8 @@ def _create_schema(schema_name, engine, schema_mustnt_exist=True):
if schema_mustnt_exist:
assert schema_name not in created_schemas
logger.debug(f'creating {schema_name}')
create_schema_if_not_exists_via_sql_alchemy(schema_name, engine)
schema_oid = get_schema_oid_from_name(schema_name, engine)
_create_schema_if_not_exists_via_sql_alchemy(schema_name, engine)
schema_oid = _get_schema_oid_from_name(schema_name, engine)
db_name = engine.url.database
created_schemas_in_this_engine = created_schemas.setdefault(db_name, {})
created_schemas_in_this_engine[schema_name] = schema_oid
Expand All @@ -223,15 +200,74 @@ def _create_schema(schema_name, engine, schema_mustnt_exist=True):
try:
for _, schema_oid in created_schemas_in_this_engine.items():
# Handle schemas being renamed during test
schema_name = get_schema_name_from_oid(schema_oid, engine)
schema_name = _get_schema_name_from_oid(schema_oid, engine)
if schema_name:
drop_sa_schema(engine, schema_name, cascade=True)
_drop_schema_via_name(engine, schema_name, cascade=True)
logger.debug(f'dropping {schema_name}')
except OperationalError as e:
logger.debug(f'ignoring operational error: {e}')
logger.debug('exit')


def _create_schema_if_not_exists_via_sql_alchemy(schema_name, engine):
return _execute_msar_func_with_engine(
engine, 'create_schema_if_not_exists', schema_name
).fetchone()[0]


def _execute_msar_func_with_engine(engine, func_name, *args):
"""
Execute an msar function using an SQLAlchemy engine.

This is temporary scaffolding.

Args:
engine: an SQLAlchemy engine for connecting to a DB
func_name: The unqualified msar function name (danger; not sanitized)
*args: The list of parameters to pass
"""
conn_str = str(engine.url)
with psycopg.connect(conn_str) as conn:
return conn.execute(
f"SELECT msar.{func_name}({','.join(['%s'] * len(args))})",
args
)


def _get_schema_name_from_oid(oid, engine, metadata=None):
schema_info = _reflect_schema(engine, oid=oid, metadata=metadata)
if schema_info:
return schema_info["name"]


def _get_schema_oid_from_name(name, engine):
schema_info = _reflect_schema(engine, name=name)
if schema_info:
return schema_info["oid"]


def _reflect_schema(engine, name=None, oid=None, metadata=None):
# If we have both arguments, the behavior is undefined.
try:
assert name is None or oid is None
except AssertionError as e:
raise e
# TODO reuse metadata
metadata = metadata if metadata else get_empty_metadata()
pg_namespace = get_pg_catalog_table("pg_namespace", engine, metadata=metadata)
sel = (
select(pg_namespace.c.oid, pg_namespace.c.nspname.label("name"))
.where(or_(pg_namespace.c.nspname == name, pg_namespace.c.oid == oid))
)
with engine.begin() as conn:
schema_info = conn.execute(sel).fetchone()
return schema_info


def _drop_schema_via_name(engine, name, cascade=False):
_execute_msar_func_with_engine(engine, 'drop_schema', name, cascade).fetchone()


# Seems to be roughly equivalent to mathesar/database/base.py::create_mathesar_engine
# TODO consider fixing this seeming duplication
# either way, both depend on Django configuration. can that be resolved?
Expand Down Expand Up @@ -260,9 +296,6 @@ def _get_connection_string(username, password, hostname, database):
ACADEMICS_SQL = os.path.join(RESOURCES, "academics_create.sql")
LIBRARY_SQL = os.path.join(RESOURCES, "library_without_checkouts.sql")
LIBRARY_CHECKOUTS_SQL = os.path.join(RESOURCES, "library_add_checkouts.sql")
FRAUDULENT_PAYMENTS_SQL = os.path.join(RESOURCES, "fraudulent_payments.sql")
PLAYER_PROFILES_SQL = os.path.join(RESOURCES, "player_profiles.sql")
MARATHON_ATHLETES_SQL = os.path.join(RESOURCES, "marathon_athletes.sql")


@pytest.fixture
Expand Down Expand Up @@ -334,54 +367,3 @@ def make_table(table_name):
in table_names
}
return tables


@pytest.fixture
def engine_with_fraudulent_payment(engine_with_schema):
engine, schema = engine_with_schema
with engine.begin() as conn, open(FRAUDULENT_PAYMENTS_SQL) as f:
conn.execute(text(f"SET search_path={schema}"))
conn.execute(text(f.read()))
yield engine, schema


@pytest.fixture
def payments_db_table(engine_with_fraudulent_payment):
engine, schema = engine_with_fraudulent_payment
metadata = MetaData(bind=engine)
table = Table("Payments", metadata, schema=schema, autoload_with=engine)
return table


@pytest.fixture
def engine_with_player_profiles(engine_with_schema):
engine, schema = engine_with_schema
with engine.begin() as conn, open(PLAYER_PROFILES_SQL) as f:
conn.execute(text(f"SET search_path={schema}"))
conn.execute(text(f.read()))
yield engine, schema


@pytest.fixture
def players_db_table(engine_with_player_profiles):
engine, schema = engine_with_player_profiles
metadata = MetaData(bind=engine)
table = Table("Players", metadata, schema=schema, autoload_with=engine)
return table


@pytest.fixture
def engine_with_marathon_athletes(engine_with_schema):
engine, schema = engine_with_schema
with engine.begin() as conn, open(MARATHON_ATHLETES_SQL) as f:
conn.execute(text(f"SET search_path={schema}"))
conn.execute(text(f.read()))
yield engine, schema


@pytest.fixture
def athletes_db_table(engine_with_marathon_athletes):
engine, schema = engine_with_marathon_athletes
metadata = MetaData(bind=engine)
table = Table("Marathon", metadata, schema=schema, autoload_with=engine)
return table
88 changes: 4 additions & 84 deletions db/columns/base.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
# TODO Remove this file once explorations are in the database
from sqlalchemy import Column, ForeignKey, inspect

from db.columns.defaults import TYPE, PRIMARY_KEY, NULLABLE, DEFAULT_COLUMNS
from db.columns.operations.select import (
get_column_attnum_from_name, get_column_default, get_column_default_dict,
)
from db.tables.operations.select import get_oid_from_table
from db.types.operations.cast import get_full_cast_map
from db.columns.operations.select import get_column_attnum_from_name
from db.types.operations.convert import get_db_type_enum_from_class


# TODO consider renaming to DbColumn or DatabaseColumn
# We are attempting to reserve the term Mathesar for types in the mathesar namespace.
class MathesarColumn(Column):
"""
This class constrains the possible arguments, enabling us to include
Expand Down Expand Up @@ -102,17 +96,6 @@ def from_column(cls, column, engine=None):
)
return new_column

def to_sa_column(self):
"""
MathesarColumn sometimes is not interchangeable with SQLAlchemy's Column.
For use in those situations, this method attempts to recreate an SA Column.

NOTE: this method is incomplete: it does not account for all properties of MathesarColumn.
"""
sa_column = Column(name=self.name, type_=self.type)
sa_column.table = self.table_
return sa_column

@property
def table_(self):
"""
Expand All @@ -128,52 +111,16 @@ def table_(self):
@property
def table_oid(self):
if self.table_ is not None:
oid = get_oid_from_table(
self.table_.name, self.table_.schema, self.engine
oid = inspect(self.engine).get_table_oid(
self.table_.name, schema=self.table_.schema
)
else:
oid = None
return oid

@property
def is_default(self):
default_def = DEFAULT_COLUMNS.get(self.name, False)
try:
self.type.python_type
except NotImplementedError:
return False
return (
default_def
and self.type.python_type == default_def[TYPE]().python_type
and self.primary_key == default_def.get(PRIMARY_KEY, False)
and self.nullable == default_def.get(NULLABLE, True)
)

def add_engine(self, engine):
self.engine = engine

@property
def valid_target_types(self):
"""
Returns a set of valid types to which the type of the column can be
altered.
"""
if (
self.engine is not None
and not self.is_default
and self.db_type is not None
):
db_type = self.db_type
valid_target_types = sorted(
list(
set(
get_full_cast_map(self.engine).get(db_type, [])
)
),
key=lambda db_type: db_type.id
)
return valid_target_types if valid_target_types else []

@property
def column_attnum(self):
"""
Expand All @@ -182,8 +129,6 @@ def column_attnum(self):
"""
engine_exists = self.engine is not None
table_exists = self.table_ is not None
# TODO are we checking here that the table exists on the database? explain why we have to do
# that.
engine_has_table = inspect(self.engine).has_table(
self.table_.name,
schema=self.table_.schema,
Expand All @@ -197,31 +142,6 @@ def column_attnum(self):
metadata=metadata,
)

@property
def column_default_dict(self):
if self.table_ is None:
return
metadata = self.table_.metadata
default_dict = get_column_default_dict(
self.table_oid, self.column_attnum, self.engine, metadata=metadata,
)
if default_dict:
return {
'is_dynamic': default_dict['is_dynamic'],
'value': default_dict['value']
}

@property
def default_value(self):
if self.table_ is not None:
metadata = self.table_.metadata
return get_column_default(
self.table_oid,
self.column_attnum,
self.engine,
metadata=metadata,
)

@property
def db_type(self):
"""
Expand Down
20 changes: 0 additions & 20 deletions db/columns/defaults.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,4 @@
from sqlalchemy import Integer

from db import constants


NAME = "name"
DESCRIPTION = "description"
NULLABLE = "nullable"
PRIMARY_KEY = "primary_key"
TYPE = "sa_type"
DEFAULT = "default"
AUTOINCREMENT = "autoincrement"

ID_TYPE = Integer


DEFAULT_COLUMNS = {
constants.ID: {
TYPE: ID_TYPE,
PRIMARY_KEY: True,
NULLABLE: False,
AUTOINCREMENT: True
}
}
Loading
Loading