Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing a mongoclient to MongoRepo does not work. Rocketry.run() fails. #193

Open
StigKorsnes opened this issue Feb 16, 2023 · 1 comment
Labels
bug Something isn't working

Comments

@StigKorsnes
Copy link

StigKorsnes commented Feb 16, 2023

Hi, cool project, but is this supposed to work?

client= MongoClient(
    "mongodb+srv://<user>:<pass>@<blabla>.a5qhe.mongodb.net/<SomeDb>?retryWrites=true&w=majority",
    server_api=ServerApi("1"),
)

mongo_repo = MongoRepo(  
    client=client,
    model=TaskRunRecord,
    database="MyDatabase",
    collection="MyCollection",
    
)
app = Rocketry(logger_repo=mongo_repo)


if __name__ == "__main__":
    app.run()

I get this Error:
pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [WinError 10061] No connection could be made because the target machine actively refused it,

Additional context
I`m on windows and using Rocketry 2.5.1. No problems what so ever with the MongoClient. I have tried several different kinds of configurations, without luck. I did manage to write few records if I instead provided the uri to MongoRepo, and set the kw arg id_field to run_id. Do not know if this is mapped to the db side _id, but it did not look like an ObjectId. I do not want under any circumstance to have anything else than a proper ObjectId for that field. Any way to make this happen, or any way I can contribute to make it happen?

UPDATE
Ok, so I realize that this issue belongs in the redbird repo. With client set, MongoSession.get_bind() tries to create a client with url of None.

@StigKorsnes StigKorsnes added the bug Something isn't working label Feb 16, 2023
@StigKorsnes
Copy link
Author

StigKorsnes commented Feb 16, 2023

This is how I deal with ObjectId`s and Pydantic models (can also be Optional field):

from pydantic import BaseModel, Field
from bson import ObjectId


class PydanticObjectId(ObjectId):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v, field):
        if not ObjectId.is_valid(v):
            raise TypeError(f"'{field.name}' must be ObjectId or valid str")
        return ObjectId(v)

    @classmethod
    def __modify_schema__(cls, field_schema):
        field_schema.update(type="ObjectId")


class MongoBase(BaseModel):
    class Config:
        allow_population_by_field_name = True
        json_encoders = {ObjectId: lambda oid: str(oid)}


class DocWithId(MongoBase):
    id: PydanticObjectId = Field(..., alias="_id")

When doing mongodb inserts or queries from with models, I export by alias. (Could possibly be refined a bit with a json decoder as well, but I'm not using it for any webapi). Another sensible thing here could be to have a default factory of objectis's, as the logger don't produce them. You would effectively produce mongo's _id-field instead of having them generated by the server on insert operations.

class DocWithFactoryId(MongoBase):
    id: PydanticObjectId = Field(default_factory=PydanticObjectId, alias="_id")

I also noticed the use of datetime.timedelta on one of the logrecord, which does not fly with pymongo. I`ve used mongomock on a couple occasions, would work well for discovering bugs like this one.

@StigKorsnes StigKorsnes changed the title BUG Passing a mongoclient to MongoRepo does not work. Rocketry.run() fails. Feb 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant