-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Figure out migrations and persistent schema #10
Comments
Do we plan on having the user maintain the database schema manually:
which seems like it would lead to some sort of one off migration system for users tracking along with the database, Or do we plan on having a construct to ensure you'll always get to the most up to date db schema whether you're tracking along or building for the first time? And I agree, I also would love not to have a DSL heavy migration story. |
Definitely a construct to ensure users are up to date. My most basic vision is basically similar to Rails, with time-stamped files that end up being SQL files. I'm unsure as of yet whether it makes sense to provide a minimal Rust DSL for common cases. The main thing for me is that any API we do provide there is immutable, as we have a huge issue in Rails with old migrations changing inadvertently. So I'm thinking we'll probably start with time-stamped SQL files and build on top of that if we feel it's needed. In all scenarios, I want to be able to switch arbitrarily between SQL files and Rust files, with the timestamp and naming convention being the thing that ties them together. |
One note is that my plan for timestamps. For those unfamiliar, in Rails we generally have two semi-magic columns called
CREATE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
BEGIN
IF (NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at) THEN
NEW.updated_at := current_timestamp;
END IF;
RETURN NEW;
END
$$ LANGUAGE plpgsql; Then for each table with timestamps, you can do: CREATE TRIGGER my_table_set_updated_at BEFORE UPDATE
ON my_table FOR EACH ROW EXECUTE PROCEDURE set_updated_at(); However, part of why I think a Rust DSL might make sense is that we can have |
Hello ! Just a drive-by on my side here, hope that helps more than introduces noise. In general - a thumbs up for a idea of starting small, with just SQL files and a convention there. My experience almost always was that the DB migration solutions converge on something close to plain SQL files. With some mechanism to order them and tell which DB instance had which script ran against it already. Sometimes there are also overrides in place, e.g. something like "in general launch this script, but if running on this super special instance, also run this other script in addition.". However, my experience is mostly in largish backend systems, so may not apply to the most common use case here. Summarizing, if diesel would support some simplistic mechanism for just running bare SQL files as migrations I would be perfectly happy. A plus for a mechanism inside the ORM that would tell me, while connecting to the DB, that "hey, it seems that the newest migration I was able to find is this, but DB has this other one as the last applied." As for taking this further, into a DSL land, I have mixed feelings here. thank you by the way, for diesel have a great day everyone ! |
I will also leave an (unrequested) comment on this matter just because I find diesel pretty interesting :) I'm mainly a Python developer and I really like the way alembic is doing it's migrations. Basically each migration is a Python file with an I'm not so sure on how you could port this idea to Rust, since this methods relies on things like dynamic importing and introspection. |
This has been resolved by #79 and b062ff1. At this time, SQL files are the only supported type of migration. Some of the plumbing for other forms is in place, however. I may revisit the possibility of a Rust DSL in the future. However, at the moment the only especially compelling benefit they would provide is being able to give you |
The needs of our own test suite after adding SQLite has pretty much sold me on the need for some kind of Rust support. I don't know that I want a full rails style DSL, but there's no way to represent I still need to think it through further, but I'm thinking we can at least support files that look like this: // timestamp_migration_name.rs
fn up<Conn: Connection>(&Conn) -> QueryResult<()> {
// do stuff
}
fn down<Conn: Connection>(&Conn) -> QueryResult<()> {
// Do the opposite stuff
} I'm still unsure if it's worth doing a rails style "change" method, where you get I'm going to spend some more time thinking about this after we finish 0.5, and probably open an issue once I've had time to collect my thoughts. |
Hi ! Thanks for sharing your thoughts openly ! |
Yes. We've DSLized a little bit in our actual tests, though the migrations are still raw SQL. I ended up not even putting what came out of it in the main diesel crate, as it was so far away from being suitable for general use. It's actually going to be a lot more complicated to make this work for real |
These are both blockers in my mind. As with rails, the schema file should be auto generated, but I would like to have a usage story that doesn't require a DSL for every possible database feature. In my mind this was going to be
Schema.toml
, but I think this might just end up beingstructure.sql
from Rails. The main benefit ofschema.rb
overstructure.sql
in the Rails world is that the former is often easier to solve merge conflicts for. This is not an issue for 0.1, or really 0.x, as it's easy to work around, but we need to figure out our story for thisThe text was updated successfully, but these errors were encountered: