-
Notifications
You must be signed in to change notification settings - Fork 994
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
Ensure all data is removed during the teardown step #1714
Conversation
Hm. After using this change in development for the past few hours I believe I now understand why we are deleting data from tables using For example, in testing a signup flow (where a "signup" is an intermediate data model that gets updated through a multi-step process) I received the following error:
I'll give this some more thought and see if I can come up with a better solution. Thoughts / preferences for how to solve would be welcome! |
Ah, understood @tctrautman Thanks for getting this started! Looping in @cannikin for all the potentially amazing ideas he (probably) has about this. |
So I would love it if this behaved the way that Rails does—the fixtures are put into the database inside of a transaction, and then at the end of the test the transaction is rolled back, leaving the database in the same state it was in when we started. But I don't think transactions were supported in Prisma when I wrote that code, or at least not in the form we would need them to be in (some way to save the transaction to a variable so it could be rolled back later). Maybe there's a way to define a named transaction in So I went more heavy handed and just tracked all models that had records created for them at the start of the test, and then delete all the records in those tables at the end of the test. I can't remember the exact reason I went with But yeah now that I'm looking I can see this being an issue in databases that enforce case sensitivity in table/column names (I ran all of this against SQLite and it didn't complain when I tried to |
Thanks for such a thoughtful response @cannikin! And thanks for connecting, @thedavidprice -- this was really helpful.
I just took a look at the Prisma docs around and as far as I can tell this is still the case 😞
Ah, yeah I assume this is what I ran into with the above error.
Edit: The below conclusions are a bit out-dated after I had a chance to take a closer look at this. Thanks, this was a great idea. I just dug into this a bit and as far as I can tell we can easily get an array of the Prisma data models (which, in Postgres, will be the names of the tables, but not other databases as you mentioned.). I haven't yet found a way to get table names specifically, but I'll take a closer look this weekend with a sqlite project to see if that turns anything else up. If I don't have any luck with that, I could take stab at writing a function to turn prisma data models into table names like so:
This assumes that I can find a way to get the database type that a user is using (seems like a safe assumption, but it's not entirely clear to me where to get that.) It would be nice to avoid this, though, so hopefully I can just find a way to get table names from Prisma. |
@cannikin whenever you have a moment I'd love to get your feedback on this. I've just updated the PR description above with my updated approach. |
Ah, I believe I've discovered another situation where It wouldn't be the most performant, but a simple solution to this would be to issue a And I'm rusty here, but maybe there's a way to do this in a single statement? |
@tctrautman I can confirm two of your assumptions:
|
Thanks @jvanbaarsen! I've updated this PR to fix the second issue with a change I've been using in local development for the last few days. |
@tctrautman Thanks! I'll make sure to check that out against my codebase to see if this solves the problem. |
@@ -50,8 +51,12 @@ const removeScenario = async (scenario) => { | |||
// get unique model names only | |||
models = Array.from(new Set(models)) | |||
|
|||
for (const model of models) { | |||
await db.$queryRaw(`DELETE FROM ${model}`) | |||
const prismaModelNames = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are now running this for every scenario, would it make sense to instead of attaching this to if a scenario is present, run this every time a test has ran? So basically make it a poor mans transaction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch -- I hadn't realized it would miss cases where we weren't using scenarios, but were adding records to the database. I believe that case is now taken care of, and I've renamed the function to reflect this.
@tctrautman I still see code changes coming in so I've been holding off on reviewing. Let me know when you think it's ready! |
Thanks @cannikin! The scope of the PR is now a little wider than it was last week (description above is up to date,) but it's ready for your review whenever you have a moment. And for what it's worth, consider it battle tested on ~35 tests I have running locally on Postgres. |
Oh damn that's way simpler. Thanks! |
@cannikin happy to do it -- thanks for the direction! |
Ah, I see this one got merged. All good -- was just going to ask if it was appropriate to use the new Prisma No need to change at this point if it's even applicable. |
This code runs after every test to remove any records that were created. We definitely don’t want to do a |
Roger that.
I start the test DB setup now with |
…ender-p1 * 'main' of github.com:redwoodjs/redwood: v0.25.0 yarn rw prisma commands now show a little tip (redwoodjs#1772) FIx typo (redwoodjs#1779) Ensure all data is removed during the teardown step (redwoodjs#1714) [v0.25] revert to @prisma/cli; recreate yarn.lock (redwoodjs#1774) use prisma db push for test DB (redwoodjs#1768) Disable --version and -v for prisma alias. (redwoodjs#1767) Rebuild Prisma Client between upgrades (redwoodjs#1155) upgrade Prisma v2.16.1 (redwoodjs#1766) [v0.25] Remove warning if you scaffold a model with a relation (redwoodjs#1757) [v0.25] Scaffolded many-to-many relationship fixes (redwoodjs#1758) add forrest and kim-adeline; update all contribs (redwoodjs#1763) Run clean and then build the js. Fix: applying afterQuery in storybook mocks (redwoodjs#1740) restructure and update Deploy command and change Setup Deploy command template [breaking] (redwoodjs#1747) Fixes prisma command when path has spaces Make tutorial work with workspaces. Add "packages/*" to the template.
This PR attempts to fix three issues with the
removeScenario
function that's run after a backend test is run:PascalCasing
.removeScenario
does not teardown records of data models that are not included in a scenario.removeScenario
function would only remove records from the database if a scenario is presentWe fix these issues by getting all prisma data models with their exact casing and issuing
DELETE
statements for each each of them, wrapping the model name in double quotes to maintain exact casing in Postgres. We do this regardless of whether or not a scenario is present, so I propose we rename this function fromremoveScenario
toteardown
.At some point in the future we will likely want to replace this with a future Prisma implementation of transactions since issuing
DELETE
statements for every data model on every test run feels wasteful.