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

Suggested Documentation Fix #233

Open
johnson2427 opened this issue Jul 12, 2022 · 1 comment
Open

Suggested Documentation Fix #233

johnson2427 opened this issue Jul 12, 2022 · 1 comment
Labels
enhancement New feature or request

Comments

@johnson2427
Copy link

johnson2427 commented Jul 12, 2022

Feature request

Context

Currently, it is suggested that we globally set the engine at the module level, and I suggest that this be removed from the documentation. Mongo suggests that you scale horizontally, actually, all NoSQL solutions should scale horizontally. Therefore, you can have many databases with the same data, just organized based on some other key. Like year, month, week, etc. If we call the engine at the global level, you remove the ability to control this properly.

Solution

I suggest that this be removed from the documentation. If it were SQL, we have a different situation here. SQL is vertically scalable, so a global call is possible. But for mongo, the solution that I am using looks like this:

from typing import Any, Iterator
from bson import ObjectId

from odmantic import AIOEngine, Model
from pydantic import BaseModel


class PyObjectId(ObjectId):
    @classmethod
    def __get_validators__(cls) -> Iterator:
        yield cls.validate

    @classmethod
    def validate(cls, v: Any) -> ObjectId:
        if not ObjectId.is_valid(v):
            raise ValueError("Invalid objectid")
        return ObjectId(v)

    @classmethod
    def __modify_schema__(cls, field_schema: Any) -> None:
        field_schema.update(type="string")



class Entries(Model):
    rank: int
    username: str
    points: float
    contest_id: str


class CreateEntriesModel(BaseModel):
    rank: int
    username: str
    points: float
    contest_id: str
    season: int

    class Config:
        allow_population_by_field_name = True
        arbitrary_types_allowed = True
        json_encoders = {ObjectId: str}
        schema_extra = {
            "example": {
                "rank": "1",
                "username": "minervaengineering",
                "points": "199.15",
                "contest_id": "123456789",
                "season": "2022"
            }
        }


@router.post("/", response_description="Add new entry", response_model=Entries)
async def create_entry(entry: CreateEntriesModel):
    engine = AIOEngine(motor_client=client, database=f"ContestEntries_{entry.season}")
    entry = Entries(
        rank=entry.rank,
        username=entry.username,
        points=entry.points,
        contest_id=entry.contest_id
    )
    await engine.save(entry)
    return entry

Alternative solutions

I attempted to make the global call work, but it's a sketchy solution. And really, unstable. This is a basic setup I decided to rainman on for the last 3 hours. it's now past 2am here, and I quite literally don't know why I felt the need to do this. You did a great job on this package, and I'd love for this to be truly scalable, and for others to not run into a brick wall because of the documentation.

Additional context

That's all! Good work!

@johnson2427 johnson2427 added the enhancement New feature or request label Jul 12, 2022
@johnson2427
Copy link
Author

Maybe not remove, but give this option as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant