Skip to content

Commit

Permalink
Merge pull request #21 from Ensembl/jalvarez/sqlalchemy_updates
Browse files Browse the repository at this point in the history
Make unit tests also compatible with SQLAlchemy 1.4.45+ and 2.0+
  • Loading branch information
JAlvarezJarreta authored Aug 20, 2024
2 parents b06a27c + f701a01 commit e35e239
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 29 deletions.
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ docs = [
"mkdocstrings",
"mkdocstrings-python",
]
mysql = [ "mysqlclient" ]
mysql = [
"mysqlclient",
]

[project.urls]
Homepage = "https://www.ensembl.org"
Expand Down
2 changes: 1 addition & 1 deletion src/ensembl/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# limitations under the License.
"""Ensembl Python general-purpose utils library."""

__version__ = "0.4.1"
__version__ = "0.4.2"

__all__ = [
"StrPath",
Expand Down
1 change: 1 addition & 0 deletions src/ensembl/utils/database/unittestdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
from ensembl.utils import StrPath
from ensembl.utils.database.dbconnection import DBConnection, StrURL


TEST_USERNAME = os.environ.get("USER", "pytestuser")


Expand Down
34 changes: 22 additions & 12 deletions tests/database/test_dbconnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,38 @@

import pytest
from pytest import FixtureRequest, param
from sqlalchemy import text, VARCHAR
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy_utils import create_database, database_exists, drop_database
from sqlalchemy import Integer, text, Sequence, String
from sqlalchemy.orm import Mapped
from sqlalchemy.engine.url import make_url
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.automap import automap_base
from sqlalchemy_utils import create_database, database_exists, drop_database

from ensembl.utils.database import DBConnection, UnitTestDB
from ensembl.utils.database.unittestdb import TEST_USERNAME
# Support both SQLAlchemy 1.4+ and 2.0+
try:
from sqlalchemy.orm import DeclarativeBase, mapped_column

class MockBase(DeclarativeBase):
"""Mock Base for testing."""

class MockBase(DeclarativeBase):
"""Mock Base for testing."""
except ImportError:
from sqlalchemy.orm import declarative_base
from sqlalchemy.schema import Column as mapped_column # type: ignore

MockBase = declarative_base() # type: ignore

from ensembl.utils.database import DBConnection, UnitTestDB
from ensembl.utils.database.unittestdb import TEST_USERNAME


class MockTable(MockBase):
"""Mock Table for testing."""

__tablename__ = "mock_table"
id: Mapped[int] = mapped_column(primary_key=True)
grp: Mapped[str] = mapped_column(VARCHAR(30))
value: Mapped[int]

id: Mapped[int] = mapped_column(Integer, Sequence("id_seq"), primary_key=True)
grp: Mapped[str] = mapped_column(String(30))
value: Mapped[int] = mapped_column(Integer)


mock_metadata = MockBase.metadata
Expand Down Expand Up @@ -93,7 +103,7 @@ def test_db_name(self) -> None:
def test_url(self) -> None:
"""Tests `DBConnection.url` property."""
expected_url = make_url(self.server).set(database=self.dbc.db_name)
assert self.dbc.url == expected_url.render_as_string(hide_password=False)
assert self.dbc.url == expected_url.render_as_string(hide_password=False) # pylint: disable=no-member

@pytest.mark.dependency(depends=["test_init"], scope="class")
def test_host(self) -> None:
Expand Down Expand Up @@ -230,7 +240,7 @@ def test_test_session_scope(self) -> None:
self.dbc.dialect == "mysql"
and self.dbc.tables["gibberish"].dialect_options["mysql"]["engine"] == "MyISAM"
):
assert len(results.all()) == 2, f"SQLite/MyISAM: 2 rows permanently added to ID {identifier}"
assert len(results.all()) == 2, f"MyISAM: 2 rows permanently added to ID {identifier}"
else:
assert (
not results.fetchall()
Expand Down
28 changes: 19 additions & 9 deletions tests/database/test_unittestdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,35 @@

import pytest
from pytest import FixtureRequest, param, raises
from sqlalchemy import text, VARCHAR
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy.schema import MetaData
from sqlalchemy_utils.functions import database_exists
from sqlalchemy import Integer, text, Sequence, String
from sqlalchemy.orm import Mapped
from sqlalchemy.schema import MetaData

from ensembl.utils.database import UnitTestDB
# Support both SQLAlchemy 1.4+ and 2.0+
try:
from sqlalchemy.orm import DeclarativeBase, mapped_column

class MockBase(DeclarativeBase):
"""Mock Base for testing."""

class MockBase(DeclarativeBase):
"""Mock Base for testing."""
except ImportError:
from sqlalchemy.orm import declarative_base
from sqlalchemy.schema import Column as mapped_column # type: ignore

MockBase = declarative_base() # type: ignore

from ensembl.utils.database import UnitTestDB


class MockTable(MockBase):
"""Mock Table for testing."""

__tablename__ = "mock_table"
id: Mapped[int] = mapped_column(primary_key=True)
grp: Mapped[str] = mapped_column(VARCHAR(30))
value: Mapped[int]

id: Mapped[int] = mapped_column(Integer, Sequence("id_seq"), primary_key=True)
grp: Mapped[str] = mapped_column(String(30))
value: Mapped[int] = mapped_column(Integer)


mock_metadata = MockBase.metadata
Expand Down
12 changes: 6 additions & 6 deletions tests/database/test_unittestdb/mock_db/table.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CREATE TABLE `gibberish` (
`id` INTEGER NOT NULL,
`grp` VARCHAR(20) DEFAULT "",
`value` INT DEFAULT NULL,
PRIMARY KEY (`id`, `grp`)
CREATE TABLE gibberish (
id INTEGER NOT NULL,
grp VARCHAR(20) DEFAULT '',
value INT DEFAULT NULL,
PRIMARY KEY (id, grp)
);
CREATE INDEX `id_idx` ON `gibberish` (`id`);
CREATE INDEX id_idx ON gibberish (id);

0 comments on commit e35e239

Please sign in to comment.