Skip to content

Commit

Permalink
fix: Address bug which fails to create schemas for MetaData beyond th…
Browse files Browse the repository at this point in the history
…e first, in a series of ordered actions.
  • Loading branch information
DanCardin committed Jun 27, 2022
1 parent c9f11f9 commit 2feca11
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 9 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pytest-mock-resources"
version = "2.4.0"
version = "2.4.1"
description = "A pytest plugin for easily instantiating reproducible mock resources."
authors = [
"Omar Khan <oakhan3@gmail.com>",
Expand Down
2 changes: 1 addition & 1 deletion src/pytest_mock_resources/compat/sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pytest_mock_resources.compat.import_ import ImportAdaptor

version = sqlalchemy.__version__
version = getattr(sqlalchemy, "__version__", "")

if version.startswith("1.4") or version.startswith("2."):
from sqlalchemy.ext import asyncio
Expand Down
10 changes: 5 additions & 5 deletions src/pytest_mock_resources/fixture/database/relational/generic.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import abc
import fnmatch
from dataclasses import dataclass
from typing import Iterable, List, Optional, Set, TypeVar, Union
from dataclasses import dataclass, field
from typing import Dict, Iterable, List, Optional, Set, TypeVar, Union

from sqlalchemy import MetaData, text
from sqlalchemy.engine import Engine
Expand Down Expand Up @@ -90,7 +90,7 @@ class EngineManager:
default_schema: Optional[str] = None
static_actions: Iterable[StaticAction] = ()

_ddl_created = False
_ddl_created: Dict[MetaData, bool] = field(default_factory=dict)

@classmethod
def create(
Expand Down Expand Up @@ -174,7 +174,7 @@ def run_dynamic_actions(self, conn):
self.execute_action(conn, action, allow_function=True)

def _create_schemas(self, conn, metadata):
if self._ddl_created:
if metadata in self._ddl_created:
return

all_schemas = {table.schema for table in metadata.tables.values() if table.schema}
Expand Down Expand Up @@ -205,7 +205,7 @@ def _create_tables(self, conn, metadata):
def create_ddl(self, conn, metadata):
self._create_schemas(conn, metadata)
self._create_tables(conn, metadata)
self._ddl_created = True
self._ddl_created[metadata] = True

def execute_action(self, conn, action, allow_function=False):
if isinstance(action, MetaData):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
import warnings

import pytest
from sqlalchemy import create_engine, event
from sqlalchemy.dialects import registry # type: ignore
from sqlalchemy import create_engine, dialects, event
from sqlalchemy.dialects.postgresql import JSON, JSONB
from sqlalchemy.dialects.sqlite import base as sqlite_base
from sqlalchemy.dialects.sqlite.pysqlite import SQLiteDialect_pysqlite
Expand Down Expand Up @@ -233,6 +232,7 @@ def create_sqlite_fixture(
if postgres_like:
dialect = make_postgres_like_sqlite_dialect()
dialect_name = dialect.name
registry = getattr(dialects, "registry")
registry.register("sqlite.{}".format(dialect_name), __name__, "PostgresLikeSQLitePDialect")

driver_name = "sqlite+{}".format(dialect_name)
Expand Down
36 changes: 36 additions & 0 deletions tests/fixture/database/test_ordered_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,39 @@ def test_non_template_database(non_template_database, run):
execute = conn.execute(text("SELECT name FROM stuffs.user")).all()
result = sorted([row[0] for row in execute])
assert ["Mug", "Perrier"] == result


class Test_multi_metadata_schemata:
"""Assert that schemas are automatically created, given more than one input MetaData.
Addresses bug which set test-state in such a way that only the first MetaData's
schemas were created.
"""

Base = declarative_base()

class Foo(Base):
__tablename__ = "foo"
__table_args__ = {"schema": "foo"}

id = Column(Integer, primary_key=True, autoincrement=True)

Base2 = declarative_base()

class Bar(Base2):
__tablename__ = "bar"
__table_args__ = {"schema": "bar"}

id = Column(Integer, primary_key=True, autoincrement=True)

multi_metadata_schemata = create_postgres_fixture(Base, Base2)

def test_creates_all_metadata_schemas(self, multi_metadata_schemata):
with multi_metadata_schemata.connect() as conn:
result = conn.execute(text("select * from foo.foo")).all()
assert len(result) == 0

result = conn.execute(text("select * from bar.bar")).all()
assert len(result) == 0
# We dont need much in the way of assertions. You would see
# database errors from the nonexistence of these schemas/tables.

0 comments on commit 2feca11

Please sign in to comment.