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

Request for guides / tutorials / documentation #175

Open
1 task
RobertCraigie opened this issue Dec 9, 2021 · 9 comments
Open
1 task

Request for guides / tutorials / documentation #175

RobertCraigie opened this issue Dec 9, 2021 · 9 comments
Labels
kind/discussion Discussion is required. kind/docs A documentation change is required.

Comments

@RobertCraigie
Copy link
Owner

RobertCraigie commented Dec 9, 2021

I am looking into improving the documentation for this project and a part of that is creating guides for using Prisma Client Python with existing frameworks.

This issue serves as the place to request that I write a tutorial / guide for any framework, please leave a comment if there is any specific framework you would like me to write a tutorial for!

Guides:

  • How to share the same schema between frontend and backend
@RobertCraigie RobertCraigie added kind/discussion Discussion is required. kind/docs A documentation change is required. labels Dec 9, 2021
@RobertCraigie RobertCraigie pinned this issue Dec 9, 2021
@RobertCraigie RobertCraigie removed the kind/discussion Discussion is required. label Dec 9, 2021
@RobertCraigie RobertCraigie added the kind/discussion Discussion is required. label Feb 2, 2022
@HOZHENWAI
Copy link

Hi,

Can we documentation on how to set up tests using the client? I'm using pytest and I have no clue if there an easy way to tear down the created objects after the tests. Moreover, is there a way to configure the client to use a mock instance of the database for testing?

Thank you.

@RobertCraigie
Copy link
Owner Author

RobertCraigie commented Nov 19, 2022

Hey @HOZHENWAI! Thanks for the suggestion, this definitely needs good documentation. In the meantime you can take a look at the conftest.py that we use internally: https://github.com/RobertCraigie/prisma-client-py/blob/main/lib/testing/shared_conftest/_shared_conftest.py

This shows how you can automatically connect to the client and cleanup the database. Let me know if anything else isn't clear / if you have any questions!

Moreover, is there a way to configure the client to use a mock instance of the database for testing?

I'd highly recommend not mocking the Prisma Client. By mocking you are leaving an important layer in your application untested. In my opinion your tests should use as little mocking as possible, only doing so when it would be difficult / expensive to not mock.

If you mock the client you could easily introduce bugs that are not caught by your tests. For example, consider the case where you're running a find_many query where you want all of the records that have a field with a value greater than the given input. By mocking the client, this interaction is never tested. You could accidentally change the query from a gt to a lt or you could be assuming the input is always positive but a negative input is given and your tests would pass.

@HOZHENWAI
Copy link

Hello @RobertCraigie. I have some issues understanding some part of the shared_conftest, so if you don't mind, I'll try to write what I understood and if you could correct me I'd be grateful:

  • it seems to me that the cleanup is done is the cleanup_client async function, what I don't understand is the process as batch_ "groups write queries into a single transaction". So I have to two questions, if we use a create or a create_many, does the result both get stored into the batch?
  • about the client_fixture, it looks like the cleanup is always done before returning the client, shouldn't it be after a yield to cleanup the database?
  • it seems to me that setup_client_fixture is actually the one cleaning up the database after each test, is it right?
  • how does the persist_data marker work, set it up for a test and the next test will have the created objects in database from the last test?
  • if i'm not wrong the event_loop should only be used for low level functions used by prisma, right, I am not sure of it's importance for high level testing.
    Thank you for your remark. TIL about mocking client.

@RobertCraigie
Copy link
Owner Author

it seems to me that the cleanup is done is the cleanup_client async function, what I don't understand is the process as batch_ "groups write queries into a single transaction". So I have to two questions, if we use a create or a create_many, does the result both get stored into the batch?

I'm not sure I understand what you mean by "does the result both get stored into the batch?". The query batching is done so that there is only one internal HTTP call (how we communicate with the Prisma Query Engine) for a slight performance improvement.

This documentation might be helpful for you if you haven't already read it: https://prisma-client-py.readthedocs.io/en/stable/reference/batching/

about the client_fixture, it looks like the cleanup is always done before returning the client, shouldn't it be after a yield to cleanup the database?

For our internal tests we don't really care what the result of the database is, just that before each test the database is clean. If you wanted to perform cleanup after a test is ran, that would be perfectly fine but you'd also want to cleanup before as well, otherwise the first test in your test suite would not have a clean database.

it seems to me that setup_client_fixture is actually the one cleaning up the database after each test, is it right?

Yes that is right, apart from that it is cleaning up the database before each test.

how does the persist_data marker work, set it up for a test and the next test will have the created objects in database from the last test?

The persist data marker works by skipping the database cleanup we do, the way it does this here:

if request.node.get_closest_marker('persist_data') is not None:

The way I use it is by defining a fixture that will be automatically ran and then decorating every test in the file with persist_data, you can see an example of this here: https://github.com/RobertCraigie/prisma-client-py/blob/main/databases/tests/test_group_by.py

I'd also like to point out that this is purely used for convenience / test speedup, you can completely omit using this in your tests.

if i'm not wrong the event_loop should only be used for low level functions used by prisma, right, I am not sure of it's importance for high level testing.

No you are completely right. The only wwreason it is there is to change the default behaviour of pytest-asyncio which will close the event loop and re-create it for each test. This is a perfectly reasonable default but it means we wouldn't be able to re-use the same Prisma client for each test and would have to connect() again which makes the tests much slower.

Thank you for your remark. TIL about mocking client.

Always happy to help!

@sammyolo
Copy link

sammyolo commented Jul 25, 2023

Could the custom generator be expanded in terms of documentation, I think it's possible but can you use custom generator like "extension" in prisma nodejs? I'd like to add methods to all my models and partials.

@RobertCraigie
Copy link
Owner Author

Yes you could use a custom generator to generate models that inherit from the default. But it should be noted that you'd have to update your code to use that everywhere which may be a bit annoying.

Unfortunately an equivalent of client extensions isn't possible due to the limitations of the Python type system.

Also unfortunately I don't have the capacity to provide an example right now but I'm happy to help if you run into any issues :)

@ntindle
Copy link

ntindle commented Nov 22, 2023

I'd love a tutorial for working with FastAPI Dependency Injection with a class that contains Prisma.

class Commons:
    def __init__(self) -> None:
        self.settings = Settings()
        self.prisma = Prisma()
        self.other_things = ...

    async def _init(self):
        await self.prisma.connect()
        self.user_storage = self.prisma.user


async def get_commons() -> Commons:
    commons = Commons()
    await commons._init()
    return commons

and then

router = APIRouter(
    prefix="/test",
    dependencies=[
		...
    ],
)

as well as

@router.post("/create_user")
async def create_user(
    request: Request,
    background_tasks: BackgroundTasks,
    commons=Depends(get_commons),
):
    await commons.prisma.user.create(data={...})

I'm almost certain there's a better way to do this without re-initing every request but I'm not familiar enough with python prisma to do it.

@Asleep123
Copy link

More documentation on updating arrays. I’m not quite sure how to append to an array with a reference to another object.

@ntindle
Copy link

ntindle commented Apr 12, 2024

Docs on how to use npm-based generators alongside the Python ones. A few examples of what I'm talking about below:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/discussion Discussion is required. kind/docs A documentation change is required.
Projects
Status: Backlog
Development

No branches or pull requests

5 participants