BeanieODM / beanie

Asynchronous Python ODM for MongoDB
http://beanie-odm.dev/
Apache License 2.0
2.01k stars 212 forks source link

migrations/test_free_fall.py fails #43

Closed jorants closed 3 years ago

jorants commented 3 years ago

Don't know if it is my setup but migrations/test_free_fall.py fails on my machine. Running mongodb v4.4.4 on arch linux, python 3.9.5.

roman-right commented 3 years ago

Interesting. I'll take a look and will add this configuration to the test pipelines. Thank you!

jorants commented 3 years ago

Ah, so it is not generally failing. Here is the error:

______________________________ test_migration_free_fall[pyloop] _______________________________

settings = Settings(mongodb_dsn='mongodb://localhost:27017', mongodb_db_name='beanie_db')
notes = None
db = AsyncIOMotorDatabase(Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=False, driver=DriverInfo(name='Motor', version='2.4.0', platform='asyncio')), 'beanie_db'))

    async def test_migration_free_fall(settings, notes, db):
        migration_settings = MigrationSettings(
            connection_uri=settings.mongodb_dsn,
            database_name=settings.mongodb_db_name,
            path="tests/migrations/migrations_for_test/free_fall",
        )
>       await run_migrate(migration_settings)

tests/migrations/test_free_fall.py:49: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
beanie/executors/migrate.py:81: in run_migrate
    await root.run(
beanie/migrations/runner.py:73: in run
    await migration_node.run_forward(
beanie/migrations/runner.py:111: in run_forward
    await self.run_migration_class(
beanie/migrations/runner.py:156: in run_migration_class
    await migration.run(session=s)
beanie/migrations/controllers/free_fall.py:26: in run
    await self.function(**function_kwargs)
tests/migrations/migrations_for_test/free_fall/20210413210446_free_fall.py:34: in name_to_title
    await new_note.replace(session=session)
beanie/odm/documents.py:303: in replace
    await self.find_one({"_id": self.id}).replace_one(
beanie/odm/queries/find.py:404: in replace_one
    await self.document_model.get_motor_collection().replace_one(
/usr/lib/python3.9/concurrent/futures/thread.py:52: in run
    result = self.fn(*self.args, **self.kwargs)
../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/collection.py:943: in replace_one
    self._update_retryable(
../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/collection.py:868: in _update_retryable
    return self.__database.client._retryable_write(
../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/mongo_client.py:1498: in _retryable_write
    return self._retry_with_session(retryable, func, s, None)
../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/mongo_client.py:1384: in _retry_with_session
    return self._retry_internal(retryable, func, session, bulk)
../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/mongo_client.py:1416: in _retry_internal
    return func(session, sock_info, retryable)
../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/collection.py:860: in _update
    return self._update(
../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/collection.py:829: in _update
    result = sock_info.command(
../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/pool.py:683: in command
    return command(self, dbname, spec, slave_ok,
../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/network.py:159: in command
    helpers._check_command_response(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

response = {'code': 20, 'codeName': 'IllegalOperation', 'errmsg': 'Transaction numbers are only allowed on a replica set member or mongos', 'ok': 0.0}
max_wire_version = 9, allowable_errors = None, parse_write_concern_error = False

    def _check_command_response(response, max_wire_version,
                                allowable_errors=None,
                                parse_write_concern_error=False):
        """Check the response to a command for errors.
        """
        if "ok" not in response:
            # Server didn't recognize our message as a command.
            raise OperationFailure(response.get("$err"),
                                   response.get("code"),
                                   response,
                                   max_wire_version)

        if parse_write_concern_error and 'writeConcernError' in response:
            _error = response["writeConcernError"]
            _labels = response.get("errorLabels")
            if _labels:
                _error.update({'errorLabels': _labels})
            _raise_write_concern_error(_error)

        if response["ok"]:
            return

        details = response
        # Mongos returns the error details in a 'raw' object
        # for some errors.
        if "raw" in response:
            for shard in itervalues(response["raw"]):
                # Grab the first non-empty raw error from a shard.
                if shard.get("errmsg") and not shard.get("ok"):
                    details = shard
                    break

        errmsg = details["errmsg"]
        code = details.get("code")

        # For allowable errors, only check for error messages when the code is not
        # included.
        if allowable_errors:
            if code is not None:
                if code in allowable_errors:
                    return
            elif errmsg in allowable_errors:
                return

        # Server is "not master" or "recovering"
        if code in _NOT_MASTER_CODES:
            raise NotMasterError(errmsg, response)
        elif "not master" in errmsg or "node is recovering" in errmsg:
            raise NotMasterError(errmsg, response)

        # Other errors
        # findAndModify with upsert can raise duplicate key error
        if code in (11000, 11001, 12582):
            raise DuplicateKeyError(errmsg, code, response, max_wire_version)
        elif code == 50:
            raise ExecutionTimeout(errmsg, code, response, max_wire_version)
        elif code == 43:
            raise CursorNotFound(errmsg, code, response, max_wire_version)

>       raise OperationFailure(errmsg, code, response, max_wire_version)
E       pymongo.errors.OperationFailure: Transaction numbers are only allowed on a replica set member or mongos, full error: {'ok': 0.0, 'errmsg': 'Transaction numbers are only allowed on a replica set member or mongos', 'code': 20, 'codeName': 'IllegalOperation'}

../../.cache/pypoetry/virtualenvs/beanie-jUTbzpV9-py3.9/lib/python3.9/site-packages/pymongo/helpers.py:164: OperationFailure
------------------------------------ Captured stderr call -------------------------------------
Building migration list
Running migrations forward without limit
Running migration name_to_title from module 20210413210446_free_fall.py
-------------------------------------- Captured log call --------------------------------------
INFO     beanie.migrations.runner:runner.py:166 Building migration list
INFO     beanie.migrations.runner:runner.py:71 Running migrations forward without limit
INFO     beanie.migrations.runner:runner.py:152 Running migration name_to_title from module 20210413210446_free_fall.py
=================================== short test summary info ===================================
FAILED tests/migrations/test_free_fall.py::test_migration_free_fall[pyloop] - pymongo.errors...
roman-right commented 3 years ago

Thank you!

Hm, it looks like your MongoDB set doesn't support transactions. It is necessary for migrations.

Could you pls share, how do you run mongodb? Is it a replica-set?

jorants commented 3 years ago

I'm pretty new to mongodb so I'm not sure but I do not think so. I installed the mongodb-bin and mongodb-tools-bin packages form the AUR (I just updated them to be sure) and started them through systemctl. mongod --version gives:

db version v4.4.4
Build Info: {
    "version": "4.4.4",
    "gitVersion": "8db30a63db1a9d84bdcad0c83369623f708e0397",
    "openSSLVersion": "OpenSSL 1.1.1k  25 Mar 2021",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2004",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
roman-right commented 3 years ago

Looks like this could be closed. Feel free to reopen, if I'm wrong.