-
Notifications
You must be signed in to change notification settings - Fork 80
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
Ecto Persistence: Customize UPSERT options for MySQL adapter #41
Conversation
ecto_sql supports UPSERT behaviour for both the MySQL and Postgres adapters. Postgres requires the `conflict_target` option be supplied when performing updates, while MySQL does not support it at all. To allow supporting both of these backends, we'll use the Repo's adapter to differentiate what kind of database we're talking to, and use that to generate the appropriate insert options.
Hi, thanks for the PR :-) All the non-ecto build tasks are failing with this:
You'll need to add a stubbed function to It's only a problem in CI because the persistence modules are condiditionally compiled, only if |
Apologies for the delayed feedback loop, Travis has been having some issues today. The updated build's just finished, with a couple failures that don't appear to be related to this patch - both of the jobs are using the Redis persistence adapter. It's possible these are one-off failures related to Travis' partial outage, but I can't ask Travis to retry the build without making an additional commit - could you hit the Retry button when you have a moment? |
Yup, they looked like flakeys. I've restarted them and now everything is green. This seems to work 👍 I'll tweak the Travis matrix after this is merged. |
Yep, it's behaving as expected with this change. |
Nice. Thank you for working on this. 👍 Before releasing a new version, I want to find a way to get the Ecto tests to run with both Postgres and MySQL in CI. |
Testing it locally with MySQL When I try to add a percentage gate I get this error, reported through Phoenix:
|
What version of MySQL are you using? |
I'm not actually certain, or able to easily tell - this app's hosting situation is somewhat opaque to the development team, for multiple reasons (part of the reason we need feature flags!). Seems like that's an issue with the in-transaction table lock for the percentage gate We're not planning to use the percentage flag functionality anytime soon, so perhaps that can be filed as a separate issue and a fix devised there? |
I see. You can try with this: SHOW VARIABLES LIKE "%version%"; If you don't have access to the Ecto.Adapters.SQL.query!(YourApp.Repo, "SHOW VARIABLES LIKE "%version%";") |
Yes, it's definitely an issue with this: The table lock is required because the unique three-column index alone wouldn't prevent duplicated rows for the percentage gates. A different table design would make the table lock not necessary, but when I added the percentage gates I was mainly concerned with keeping it a small and retro-compatible version update. Perhaps it's something I could revisit for version 2.0.
I'm more a Postgres person too. I've looked at the MySQL docs for table locking, and it's not really clear to me yet what the right pattern is. The fact that locks are not released when a transaction commits or rolls back is concerning.
I see your point, but in that case I suggest you use your fork instead of getting this partial fix merged. Since with this alone I can't really claim that "it now works with MySQL", I wouldn't release a new version for it -- I wouldn't even keep it on the master branch, but on a The reason is that this is the first time I hear about this problem. I suspect that the reason is most people are using this package with either Redis or Ecto+Postgres; if anyone else tried to use it with MySQL in the past and got blocked because of the problem you encountered, they didn't bother reporting it here on GitHub. At the moment the situation seems to be that most users of the package can use it fine with their set up, and I could just add to the docs that the Ecto adapter works with Postgres only, even though it's not ideal. On the other hand, if I were to merge this as it is, I wouldn't really consider it ready for release. The changelog entry would be: "now it partially works with MySQL, but not everything". 🤔 So I'd rather either fix everything or nothing at all. I'll now create a new |
I've amended the docs: a2e8e44 And I've created the |
Update: I've given a stub at running the tests on MySQL. Currently a bit blocked locally because of this: xerions/mariaex#222 That issue also seems to suggest that |
Thanks for the README update. Based on the other discoveries in this thread, I think it's reasonable to use a I am reasonably confident we're using a |
Ok, I've had to downgrade my local env from MySQL 8.0 to 5.7, and now Mariaex can connect. I'll now merge this and add some travis tasks for MySQL specifically. |
ecto_sql
supports UPSERT operations for both the MySQL and Postgres adapters. Postgres requires theconflict_target
option be supplied when performing updates, while MySQL does not support it at all.To allow supporting both of these backends, we'll use the Repo's adapter to differentiate what kind of database we're talking to, and use that to generate the appropriate insert options.
This addresses #40. As mentioned in that issue,
.travis.yml
changes are required to begin testing against both MySQL and Postgres backends - I wasn't fully comfortable making those changes myself, as the existing build matrix and test setup is reasonably complex.