Search code examples
postgresqlpytestpsycopg2importerror

pytest_postgresql example raises import error psycopg


I am currently trying to get pytest_postgresql running in my enviroment. befor I start: I can test the sql code it self with this right? not just things like your database connection would work like this?

so I copyed the Sample test out of github readme:

def test_example_postgres(postgresql):
    """Check main postgresql fixture."""
    cur = postgresql.cursor()
    cur.execute("CREATE TABLE test (id serial PRIMARY KEY, num integer, data varchar);")
    postgresql.commit()
    cur.close()

than I tryed: pytest

I got:


================================================================================================================= ERRORS =================================================================================================================
________________________________________________________________________________________________ ERROR at setup of test_example_postgres _________________________________________________________________________________________________

request = <SubRequest 'postgresql' for <Function test_example_postgres>>

    @pytest.fixture
    def postgresql_factory(request: FixtureRequest) -> Iterator[connection]:
        """
        Fixture factory for PostgreSQL.

        :param request: fixture request object
        :returns: postgresql client
        """
>       check_for_psycopg()

venv\lib\site-packages\pytest_postgresql\factories\client.py:56:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    def check_for_psycopg() -> None:
        """
        Function checks whether psycopg was imported.

        Raises ImportError if not.
        """
        if not psycopg:
>           raise ImportError("No module named psycopg. Please install psycopg.")
E           ImportError: No module named psycopg. Please install psycopg.

venv\lib\site-packages\pytest_postgresql\compat.py:35: ImportError
======================================================================================================== short test summary info =========================================================================================================
ERROR test_postgresql.py::test_example_postgres - ImportError: No module named psycopg. Please install psycopg.
============================================================================================================ 1 error in 0.12s ============================================================================================================

So I tryed: pip install psycopg

I got:


Requirement already satisfied: psycopg in c:\users\a05922\pycharmprojects\try_out_pytest_postgresql\venv\lib\site-packages (3.0.9)
Requirement already satisfied: tzdata in c:\users\a05922\pycharmprojects\try_out_pytest_postgresql\venv\lib\site-packages (from psycopg) (2021.5)

So I thought if I import it python may realise that the package is already installed:

import psycopg


def test_example_postgres(postgresql):
    """Check main postgresql fixture."""
    cur = postgresql.cursor()
    cur.execute("CREATE TABLE test (id serial PRIMARY KEY, num integer, data varchar);")
    postgresql.commit()
    cur.close()

I tried: pytest

I got:


========================================================================================================== test session starts ===========================================================================================================
platform win32 -- Python 3.9.4, pytest-7.0.1, pluggy-1.0.0
rootdir: C:\Users\a05922\PycharmProjects\try_out_pytest_postgresql
plugins: postgresql-4.1.0
collected 0 items / 1 error                                                                                                                                                                                                               

================================================================================================================= ERRORS =================================================================================================================
__________________________________________________________________________________________________ ERROR collecting test_postgresql.py ___________________________________________________________________________________________________
ImportError while importing test module 'C:\Users\a05922\PycharmProjects\try_out_pytest_postgresql\test_postgresql.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
C:\Programme\Python\Python39\lib\importlib\__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
test_postgresql.py:1: in <module>
    import psycopg
venv\lib\site-packages\psycopg\__init__.py:9: in <module>
    from . import pq  # noqa: F401 import early to stabilize side effects
venv\lib\site-packages\psycopg\pq\__init__.py:114: in <module>
    import_from_libpq()
venv\lib\site-packages\psycopg\pq\__init__.py:106: in import_from_libpq
    raise ImportError(
E   ImportError: no pq wrapper available.
E   Attempts made:
E   - couldn't import psycopg 'c' implementation: No module named 'psycopg_c'
E   - couldn't import psycopg 'binary' implementation: No module named 'psycopg_binary'
E   - couldn't import psycopg 'python' implementation: libpq library not found
======================================================================================================== short test summary info =========================================================================================================
ERROR test_postgresql.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
============================================================================================================ 1 error in 0.15s ============================================================================================================

this is where i ran out of ideas what to try next. I tried googleing the problem but i cam up empty handed. Has anyone an idea how I can fix this?

edit:

atfter suggestion of pip uninstall psycopg then pip install psycopg[binary]

I got:

Microsoft Windows [Version 10.0.18363.2094]
(c) 2019 Microsoft Corporation. Alle Rechte vorbehalten.

(venv) C:\Users\a05922\PycharmProjects\try_out_pytest_postgresql>pip install psycopg
Requirement already satisfied: psycopg in c:\users\a05922\pycharmprojects\try_out_pytest_postgresql\venv\lib\site-packages (3.0.9)
Requirement already satisfied: tzdata in c:\users\a05922\pycharmprojects\try_out_pytest_postgresql\venv\lib\site-packages (from psycopg) (2021.5)

(venv) C:\Users\a05922\PycharmProjects\try_out_pytest_postgresql>pip install psycopg[binary]
Requirement already satisfied: psycopg[binary] in c:\users\a05922\pycharmprojects\try_out_pytest_postgresql\venv\lib\site-packages (3.0.9)
Requirement already satisfied: tzdata in c:\users\a05922\pycharmprojects\try_out_pytest_postgresql\venv\lib\site-packages (from psycopg[binary]) (2021.5)
Collecting psycopg-binary==3.0.9
  Downloading psycopg_binary-3.0.9-cp39-cp39-win_amd64.whl (2.9 MB)
     ---------------------------------------- 2.9/2.9 MB 10.3 MB/s eta 0:00:00
Installing collected packages: psycopg-binary
Successfully installed psycopg-binary-3.0.9

pytest got me:


========================================================================================================== test session starts ===========================================================================================================
platform win32 -- Python 3.9.4, pytest-7.0.1, pluggy-1.0.0
rootdir: C:\Users\a05922\PycharmProjects\try_out_pytest_postgresql
plugins: postgresql-4.1.0
collected 1 item                                                                                                                                                                                                                          

test_postgresql.py E                                                                                                                                                                                                                [100%]

================================================================================================================= ERRORS =================================================================================================================
________________________________________________________________________________________________ ERROR at setup of test_example_postgres _________________________________________________________________________________________________

request = <SubRequest 'postgresql' for <Function test_example_postgres>>

    @pytest.fixture
    def postgresql_factory(request: FixtureRequest) -> Iterator[connection]:
        """
        Fixture factory for PostgreSQL.

        :param request: fixture request object
        :returns: postgresql client
        """
        check_for_psycopg()
>       proc_fixture: Union[PostgreSQLExecutor, NoopExecutor] = request.getfixturevalue(
            process_fixture_name
        )

venv\lib\site-packages\pytest_postgresql\factories\client.py:57:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
venv\lib\site-packages\pytest_postgresql\factories\process.py:104: in postgresql_proc_fixture
    pg_bindir = subprocess.check_output(
C:\Programme\Python\Python39\lib\subprocess.py:424: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
C:\Programme\Python\Python39\lib\subprocess.py:505: in run
    with Popen(*popenargs, **kwargs) as process:
C:\Programme\Python\Python39\lib\subprocess.py:951: in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <Popen: returncode: None args: ['pg_config', '--bindir']>, args = 'pg_config --bindir', executable = None, preexec_fn = None, close_fds = False, pass_fds = (), cwd = None, env = None
startupinfo = <subprocess.STARTUPINFO object at 0x000002A882A007C0>, creationflags = 0, shell = False, p2cread = Handle(880), p2cwrite = -1, c2pread = 14, c2pwrite = Handle(748), errread = -1, errwrite = Handle(632)
unused_restore_signals = True, unused_gid = None, unused_gids = None, unused_uid = None, unused_umask = -1, unused_start_new_session = False

    def _execute_child(self, args, executable, preexec_fn, close_fds,
                       pass_fds, cwd, env,
                       startupinfo, creationflags, shell,
                       p2cread, p2cwrite,
                       c2pread, c2pwrite,
                       errread, errwrite,
                       unused_restore_signals,
                       unused_gid, unused_gids, unused_uid,
                       unused_umask,
                       unused_start_new_session):
        """Execute program (MS Windows version)"""

        assert not pass_fds, "pass_fds not supported on Windows."

        if isinstance(args, str):
            pass
        elif isinstance(args, bytes):
            if shell:
                raise TypeError('bytes args is not allowed on Windows')
            args = list2cmdline([args])
        elif isinstance(args, os.PathLike):
            if shell:
                raise TypeError('path-like args is not allowed when '
                                'shell is true')
            args = list2cmdline([args])
        else:
            args = list2cmdline(args)

        if executable is not None:
            executable = os.fsdecode(executable)

        # Process startup details
        if startupinfo is None:
            startupinfo = STARTUPINFO()
        else:
            # bpo-34044: Copy STARTUPINFO since it is modified above,
            # so the caller can reuse it multiple times.
            startupinfo = startupinfo.copy()

        use_std_handles = -1 not in (p2cread, c2pwrite, errwrite)
        if use_std_handles:
            startupinfo.dwFlags |= _winapi.STARTF_USESTDHANDLES
            startupinfo.hStdInput = p2cread
            startupinfo.hStdOutput = c2pwrite
            startupinfo.hStdError = errwrite

        attribute_list = startupinfo.lpAttributeList
        have_handle_list = bool(attribute_list and
                                "handle_list" in attribute_list and
                                attribute_list["handle_list"])

        # If we were given an handle_list or need to create one
        if have_handle_list or (use_std_handles and close_fds):
            if attribute_list is None:
                attribute_list = startupinfo.lpAttributeList = {}
            handle_list = attribute_list["handle_list"] = \
                list(attribute_list.get("handle_list", []))

            if use_std_handles:
                handle_list += [int(p2cread), int(c2pwrite), int(errwrite)]

            handle_list[:] = self._filter_handle_list(handle_list)

            if handle_list:
                if not close_fds:
                    warnings.warn("startupinfo.lpAttributeList['handle_list'] "
                                  "overriding close_fds", RuntimeWarning)

                # When using the handle_list we always request to inherit
                # handles but the only handles that will be inherited are
                # the ones in the handle_list
                close_fds = False

        if shell:
            startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = _winapi.SW_HIDE
            comspec = os.environ.get("COMSPEC", "cmd.exe")
            args = '{} /c "{}"'.format (comspec, args)

        if cwd is not None:
            cwd = os.fsdecode(cwd)

        sys.audit("subprocess.Popen", executable, args, cwd, env)

        # Start the process
        try:
>           hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                                     # no special security
                                     None, None,
                                     int(not close_fds),
                                     creationflags,
                                     env,
                                     cwd,
                                     startupinfo)
E                                    FileNotFoundError: [WinError 2] Das System kann die angegebene Datei nicht finden

C:\Programme\Python\Python39\lib\subprocess.py:1420: FileNotFoundError
======================================================================================================== short test summary info =========================================================================================================
ERROR test_postgresql.py::test_example_postgres - FileNotFoundError: [WinError 2] Das System kann die angegebene Datei nicht finden
============================================================================================================ 1 error in 0.35s ============================================================================================================

The German line at the end says: "The System can not finde the stated file"

I have a hard time figering this out. the argument that looks the most like a file name to me is cwd. that argument is created a few lines above from fsdecode as long as cwd already exists.

is the line:

self = <Popen: returncode: None args: ['pg_config', '--bindir']>, args = 'pg_config --bindir', executable = None, preexec_fn = None, close_fds = False, pass_fds = (), cwd = None, env = None
startupinfo = <subprocess.STARTUPINFO object at 0x000002A882A007C0>, creationflags = 0, shell = False, p2cread = Handle(880), p2cwrite = -1, c2pread = 14, c2pwrite = Handle(748), errread = -1, errwrite = Handle(632)
unused_restore_signals = True, unused_gid = None, unused_gids = None, unused_uid = None, unused_umask = -1, unused_start_new_session = False

the arguments _execute_child is called with? if so cwd would be None and could not be the problem. Anyone any ideas?


Solution

  • If you did the original install as pip install psycopg you got the pure Python version. Per Installation instructions Pure Python installation that means you need to have the libpq library installed also. Not sure how you would get that on Windows. I would say the solution is to:

    pip uninstall psycopg

    then

    pip install psycopg[binary]

    This will get you the self-contained(all needed libraries) install.