-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Support for multiple statements in Cassandra cql migration files #76
Conversation
…d on semi-colon and newline.
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.
Have you read this?
migrate
has avoid parsing the migration files b/c it's more complicate than it seems.
Upfront, I see a few issues:
- You could break up a valid query that contains a semi-colon. e.g. embedded in a string
- Partial failures. How do you handle a query that fails in the middle of a single migration? Is the migration wrapped in a transaction?
- Backwards compatibility. This shouldn't break existing migrations and with the first issue I mentioned, it's likely to. Add an option to the db driver to use batches instead of a single query.
Also, I'm not familiar enough w/ Cassandra to know if multiple statements are disallowed in a single query.
database/cassandra/cassandra.go
Outdated
for _, q := range(queries) { | ||
tq := strings.TrimSpace(q) | ||
if (tq == "") { continue } | ||
if err := c.session.Query(tq).Exec(); err != nil { |
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.
You might be better off using Batch since atomicity is guaranteed. But I'm still not sure about parsing the migration data.
I didn't see that link, that's probably worth adding to the CONTRIBUTING.md file. Responses to your other issues are below:
I agree with your basic concern, but the issue arises from the gocql library (and somewhat Cassandra itself). Apparently, Cassandra can only support a single statement per "session.Query" call. This makes this library very tedious for Cassandra, in that I need to make a separate migration file per individual schema change. How do you feel about adding a param to the connection url? Or adding a header comment that denotes this migration should be parsed into multiple statements? (BTW, this issue was brought up before it was forked here (mattes/migrate#338) and here (apache/cassandra-gocql-driver#1063) |
Thanks for the context! I think an option like Although having headers in the migration file offers more control and granularity, it introduces additional parsing of the migration files which I'd like to avoid to maintain simplicity. |
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.
Add tests
database/cassandra/cassandra.go
Outdated
return database.Error{OrigErr: err, Err: "migration failed", Query: migr} | ||
|
||
// split query by semi-colon | ||
queries := strings.Split(query, ";\n") |
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.
Don't split on \n
so we don't need to deal with different line endings
Sounds good. I have some other work to get done but I'll try to make these changes over the next couple of days. |
Ok I just pushed support for the |
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.
Thanks for addressing the feedback! There are only a few more minor issues remaining.
database/cassandra/README.md
Outdated
@@ -3,6 +3,7 @@ | |||
* Drop command will not work on Cassandra 2.X because it rely on | |||
system_schema table which comes with 3.X | |||
* Other commands should work properly but are **not tested** | |||
* The Cassandra driver (gocql) does not natively support executing multipe statements in a single query. To allow for multiple statements in a single migration, you can use the `x-multi-statement` param. Note that this simply splits the migration into separately-executed statements by a semi-colon ';'. The queries are also not executed in any sort of transaction/batch, meaning you are responsible for fixing partial migrations. |
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.
Use `;`
instead of ';'
and provide an explicit warning about semi-colons in strings causing issues.
database/cassandra/cassandra.go
Outdated
return database.Error{OrigErr: err, Err: "migration failed", Query: migr} | ||
} | ||
} | ||
} else { |
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.
return
in the if
block above and remove the else
to save a level of indentation
https://github.com/golang/go/wiki/CodeReviewComments#indent-error-flow
Additional requested changes fixed. |
Thanks for your PR! |
Currently you cannot include multiple statements in the CQL migration files due to Cassandra only allowing 1 statement per query. This makes creating multiple tables or indices in a single migration difficult. This change splits the CQL migration script by a semi-colon and newline pattern, and iterates them 1 by 1, allowing multiple statements per migration.