django-fluent / django-fluent-pages

A flexible, scalable CMS with custom node types, and flexible block content.
http://django-fluent.org/
Other
109 stars 27 forks source link

Not exist table "fluent_pages_redirectnode_translation" #150

Closed Railkhayrullin closed 2 years ago

Railkhayrullin commented 2 years ago

I have problems with English, I wrote through a translator.

requirements:

description: When testing a Django application using pytest, a test database is created using a decorator:

@pytest.mark.django_db
def test():
    # some code
    ...

Migrations are applied in the test database, and then an error appears about the absence of the fluent_pages_redirectnode_translation table:

  ...
  Applying user_reviews.0006_auto_20210726_1521... OK
  Applying user_reviews.0007_auto_20210729_1423... OK
  Applying video.0001_initial... OK
  Applying video.0002_auto_20210524_1508... OK
  Applying video.0003_alter_videoitem_block... OK
  Applying video.0004_auto_20210524_1703... OK
Creating test database for alias 'default' ('test_postgres')...
Got an error creating the test database: database "test_postgres" already exists

Destroying old test database for alias 'default' ('test_postgres')...

test setup failed
self = <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>
sql = 'SELECT "fluent_pages_redirectnode_translation"."id", "fluent_pages_redirectnode_translation"."language_code", "fluent...on"."master_id" FROM "fluent_pages_redirectnode_translation" ORDER BY "fluent_pages_redirectnode_translation"."id" ASC'
params = ()
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f64a28427f0>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>})

    def _execute(self, sql, params, *ignored_wrapper_args):
        self.db.validate_no_broken_transaction()
        with self.db.wrap_database_errors:
            if params is None:
                # params default might be backend specific.
                return self.cursor.execute(sql)
            else:
>               return self.cursor.execute(sql, params)
E               psycopg2.errors.UndefinedTable: relation "fluent_pages_redirectnode_translation" does not exist
E               LINE 1: ..._pages_redirectnode_translation"."master_id" FROM "fluent_pa...
E                                                                            ^

../../venv/lib/python3.8/site-packages/django/db/backends/utils.py:84: UndefinedTable

The above exception was the direct cause of the following exception:

self = <django.db.models.sql.compiler.SQLCompiler object at 0x7f649feda670>
result_type = 'multi', chunked_fetch = True, chunk_size = 2000

    def execute_sql(self, result_type=MULTI, chunked_fetch=False, chunk_size=GET_ITERATOR_CHUNK_SIZE):
        """
        Run the query against the database and return the result(s). The
        return value is a single data item if result_type is SINGLE, or an
        iterator over the results if the result_type is MULTI.

        result_type is either MULTI (use fetchmany() to retrieve all rows),
        SINGLE (only retrieve a single row), or None. In this last case, the
        cursor is returned if any query is executed, since it's used by
        subclasses such as InsertQuery). It's possible, however, that no query
        is needed, as the filters describe an empty set. In that case, None is
        returned, to avoid any unnecessary database interaction.
        """
        result_type = result_type or NO_RESULTS
        try:
            sql, params = self.as_sql()
            if not sql:
                raise EmptyResultSet
        except EmptyResultSet:
            if result_type == MULTI:
                return iter([])
            else:
                return
        if chunked_fetch:
            cursor = self.connection.chunked_cursor()
        else:
            cursor = self.connection.cursor()
        try:
>           cursor.execute(sql, params)

../../venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py:1169: 

cursor = <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>
sql = 'SELECT "fluent_pages_redirectnode_translation"."id", "fluent_pages_redirectnode_translation"."language_code", "fluent...on"."master_id" FROM "fluent_pages_redirectnode_translation" ORDER BY "fluent_pages_redirectnode_translation"."id" ASC'
args = ((),), kwargs = {}
connection = <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f64a28427f0>

    @wraps(original)
    def inner(cursor, sql, *args, **kwargs):
        try:
>           return original(cursor, sql, *args, **kwargs)

../../venv/lib/python3.8/site-packages/cachalot/monkey_patch.py:129: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>
sql = 'SELECT "fluent_pages_redirectnode_translation"."id", "fluent_pages_redirectnode_translation"."language_code", "fluent...on"."master_id" FROM "fluent_pages_redirectnode_translation" ORDER BY "fluent_pages_redirectnode_translation"."id" ASC'
params = ()

    def execute(self, sql, params=None):
>       return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)

../../venv/lib/python3.8/site-packages/django/db/backends/utils.py:66: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>
sql = 'SELECT "fluent_pages_redirectnode_translation"."id", "fluent_pages_redirectnode_translation"."language_code", "fluent...on"."master_id" FROM "fluent_pages_redirectnode_translation" ORDER BY "fluent_pages_redirectnode_translation"."id" ASC'
params = (), many = False
executor = <bound method CursorWrapper._execute of <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>>

    def _execute_with_wrappers(self, sql, params, many, executor):
        context = {'connection': self.db, 'cursor': self}
        for wrapper in reversed(self.db.execute_wrappers):
            executor = functools.partial(wrapper, executor)
>       return executor(sql, params, many, context)

../../venv/lib/python3.8/site-packages/django/db/backends/utils.py:75: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>
sql = 'SELECT "fluent_pages_redirectnode_translation"."id", "fluent_pages_redirectnode_translation"."language_code", "fluent...on"."master_id" FROM "fluent_pages_redirectnode_translation" ORDER BY "fluent_pages_redirectnode_translation"."id" ASC'
params = ()
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f64a28427f0>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>})

    def _execute(self, sql, params, *ignored_wrapper_args):
        self.db.validate_no_broken_transaction()
        with self.db.wrap_database_errors:
            if params is None:
                # params default might be backend specific.
                return self.cursor.execute(sql)
            else:
>               return self.cursor.execute(sql, params)

../../venv/lib/python3.8/site-packages/django/db/backends/utils.py:84: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.utils.DatabaseErrorWrapper object at 0x7f64a0428be0>
exc_type = <class 'psycopg2.errors.UndefinedTable'>
exc_value = UndefinedTable('relation "fluent_pages_redirectnode_translation" does not exist\nLINE 1: ..._pages_redirectnode_translation"."master_id" FROM "fluent_pa...\n                                                             ^\n')
traceback = <traceback object at 0x7f649fcefd40>

    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is None:
            return
        for dj_exc_type in (
                DataError,
                OperationalError,
                IntegrityError,
                InternalError,
                ProgrammingError,
                NotSupportedError,
                DatabaseError,
                InterfaceError,
                Error,
        ):
            db_exc_type = getattr(self.wrapper.Database, dj_exc_type.__name__)
            if issubclass(exc_type, db_exc_type):
                dj_exc_value = dj_exc_type(*exc_value.args)
                # Only set the 'errors_occurred' flag for errors that may make
                # the connection unusable.
                if dj_exc_type not in (DataError, IntegrityError):
                    self.wrapper.errors_occurred = True
>               raise dj_exc_value.with_traceback(traceback) from exc_value

../../venv/lib/python3.8/site-packages/django/db/utils.py:90: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>
sql = 'SELECT "fluent_pages_redirectnode_translation"."id", "fluent_pages_redirectnode_translation"."language_code", "fluent...on"."master_id" FROM "fluent_pages_redirectnode_translation" ORDER BY "fluent_pages_redirectnode_translation"."id" ASC'
params = ()
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f64a28427f0>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7f64a013ee50>})

    def _execute(self, sql, params, *ignored_wrapper_args):
        self.db.validate_no_broken_transaction()
        with self.db.wrap_database_errors:
            if params is None:
                # params default might be backend specific.
                return self.cursor.execute(sql)
            else:
>               return self.cursor.execute(sql, params)
E               django.db.utils.ProgrammingError: relation "fluent_pages_redirectnode_translation" does not exist
E               LINE 1: ..._pages_redirectnode_translation"."master_id" FROM "fluent_pa...
E                                                                            ^

../../venv/lib/python3.8/site-packages/django/db/backends/utils.py:84: ProgrammingError

During handling of the above exception, another exception occurred:

request = <SubRequest '_django_db_marker' for <Function test_default_phone_for_primary_domain>>

    @pytest.fixture(autouse=True)
    def _django_db_marker(request) -> None:
        """Implement the django_db marker, internal to pytest-django."""
        marker = request.node.get_closest_marker("django_db")
        if marker:
>           request.getfixturevalue("_django_db_helper")

../../venv/lib/python3.8/site-packages/pytest_django/plugin.py:465: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../venv/lib/python3.8/site-packages/pytest_django/fixtures.py:122: in django_db_setup
    db_cfg = setup_databases(
../../venv/lib/python3.8/site-packages/django/test/utils.py:179: in setup_databases
    connection.creation.create_test_db(
../../venv/lib/python3.8/site-packages/django/db/backends/base/creation.py:90: in create_test_db
    self.connection._test_serialized_contents = self.serialize_db_to_string()
../../venv/lib/python3.8/site-packages/django/db/backends/base/creation.py:136: in serialize_db_to_string
    serializers.serialize("json", get_objects(), indent=None, stream=out)
../../venv/lib/python3.8/site-packages/django/core/serializers/__init__.py:129: in serialize
    s.serialize(queryset, **options)
../../venv/lib/python3.8/site-packages/django/core/serializers/base.py:90: in serialize
    for count, obj in enumerate(queryset, start=1):
../../venv/lib/python3.8/site-packages/django/db/backends/base/creation.py:133: in get_objects
    yield from queryset.iterator()
../../venv/lib/python3.8/site-packages/django/db/models/query.py:353: in _iterator
    yield from self._iterable_class(self, chunked_fetch=use_chunked_fetch, chunk_size=chunk_size)
../../venv/lib/python3.8/site-packages/django/db/models/query.py:51: in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
../../venv/lib/python3.8/site-packages/cachalot/monkey_patch.py:29: in inner
    return original(compiler, *args, **kwargs)
../../venv/lib/python3.8/site-packages/cachalot/monkey_patch.py:88: in inner
    return _get_result_or_execute_query(
../../venv/lib/python3.8/site-packages/cachalot/monkey_patch.py:56: in _get_result_or_execute_query
    result = execute_query_func()
../../venv/lib/python3.8/site-packages/cachalot/monkey_patch.py:72: in <lambda>
    execute_query_func = lambda: original(compiler, *args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.db.models.sql.compiler.SQLCompiler object at 0x7f649feda670>
result_type = 'multi', chunked_fetch = True, chunk_size = 2000

    def execute_sql(self, result_type=MULTI, chunked_fetch=False, chunk_size=GET_ITERATOR_CHUNK_SIZE):
        """
        Run the query against the database and return the result(s). The
        return value is a single data item if result_type is SINGLE, or an
        iterator over the results if the result_type is MULTI.

        result_type is either MULTI (use fetchmany() to retrieve all rows),
        SINGLE (only retrieve a single row), or None. In this last case, the
        cursor is returned if any query is executed, since it's used by
        subclasses such as InsertQuery). It's possible, however, that no query
        is needed, as the filters describe an empty set. In that case, None is
        returned, to avoid any unnecessary database interaction.
        """
        result_type = result_type or NO_RESULTS
        try:
            sql, params = self.as_sql()
            if not sql:
                raise EmptyResultSet
        except EmptyResultSet:
            if result_type == MULTI:
                return iter([])
            else:
                return
        if chunked_fetch:
            cursor = self.connection.chunked_cursor()
        else:
            cursor = self.connection.cursor()
        try:
            cursor.execute(sql, params)
        except Exception:
            # Might fail for server-side cursors (e.g. connection closed)
>           cursor.close()
E           psycopg2.errors.InvalidCursorName: cursor "_django_curs_140070517139264_sync_12" does not exist

../../venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py:1172: InvalidCursorName

I also want to note that the database has a fluent_pages_urlnode_translation table with the required fields of the missing table fluent_pages_redirectnode_translation. The error comes out when testing via tox and also directly via pytest.

Railkhayrullin commented 2 years ago

Solved the problem by adding 'fluent_pages.page type.redirectnode', to INSTALLED_APPS, but redirect node is not used in the application.