-
Notifications
You must be signed in to change notification settings - Fork 67
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
failed to rename columns #8
Comments
This is a limitation of any "schema diff" program, like Pyrseas, apgdiff and others. I blogged about this here: http://pyrseas.wordpress.com/2011/04/21/sql-database-version-control-and-renames/ . If you rename an object (column, table, etc.), there is nothing in the PostgreSQL catalogs that keeps the previous name. The solution we suggest is to edit the YAML output and add an 'oldname: c4' under the 'cc4' column spec. Then yamltodb will generate the correct ALTER TABLE RENAME COLUMN statement. We think this is better than dropping the column and recreating it with the new name. Having said, I will take a look at why it's generating ALTER TABLE DROP COLUMN cc4, instead of ALTER TABLE DROP COLUMN c4 followed by ALTER TABLE ADD COLUMN cc4. |
@melezhik, in my testing, after the RENAME COLUMN, the yamltodb output is to DROP COLUMN c4, not cc4. Can you please confirm that is a typo on your part? Also, I think your last sentence should read "which is wrong, because only drop column c4, but also has to create column cc4!" |
no, the sentence is correct. I see the limitation, but would not it be better to raise exception in this case? something like |
OK, I guess I misunderstood the intent of your example. You're running everything against the same database and the ALTER TABLE RENAME COLUMN is a statement that you'd want to back out. Is that correct? In other words, you want to reinstate the previous schema and undo the RENAME. I don't think raising an exception is a useful default because that missing/renamed/dropped objects are rather common in version control. I can see three possible solutions:
|
For the record, behaviors 1 and 3 already work at the table level, e.g.,
The issue is when a column is renamed, e.g.,
I agree what is necessary is an ALTER TABLE t1 ADD COLUMN c2 text, in addition to the command issued above. Later we can talk about behavior 2, i.e., some exception or warning based on a user-specified option. |
yes, correct!
yes, this would be good if these 3 cases would be available through usage of Pyrseas |
* pyrseas/dbobject/column.py (ColumnDict.diff_map): Don't attempt to drop columns that have already been dropped in the catalogs (caused innocuous semicolons on output). * pyrseas/dbobject/table.py (Table.diff_map): Examine existing columns and generate ADD COLUMN statements if not present in the input map.
Hi, @jmafc, how can I see the changes? (Via git clone ... and install?) |
Hi Alexey, If you just want to see the changes, simply click on the 1a575b5 link. If you want to install the changes, you could do a |
ok, after upgrading code still have the same behavior:
|
@melezhik hmm, I could've sworn ... Sorry, I guess I'll have to follow my own test-driven development guidelines and write a unit test case first, and then (re)write the fix. |
* pyrseas/dbobject/table.py (Table.diff_map): Calculate number of columns present excluding dropped columns. For columns out of order, add them if not in list of existing columns. * tests/dbobject/__init__.py: Invoke column tests. * tests/dbobject/test_column.py: New tests for dropping and adding columns, plus move other colum tests from test_table.py. * tests/dbobject/test_table.py: Move columns tests to new module.
OK, I checked it out, now it works as proposed, thank you! What about:
-- the command line flag will be included in v0.4.1? |
No, the command line option is a future enhancement. I'm still not sure if the option should be specific to columns, e.g., --fail-missing-columns, or more general --fail-missing-objects, i.e., to raise an exception instead of emitting DROP statements for missing tables, indexes, etc. The main use case for dbtoyaml/yamltodb was development, where dropping, renaming and other changes are commonplace. |
Ok, I understand |
I'm starting to implement this. I've settled on a schema public:
description: standard public schema
table t1:
columns:
- c1:
type: integer
- c2:
type: text
- c3:
type: date And someone has done Is that correct? Is there some other case I should consider? |
yeah, sounds good, I guess it'd better to say something: |
Well, I'm not native English either (but I was exposed to it very early). Anyhow, the issue is we only detect that something is missing two layers deep (in Do you also want to get an error for the converse situation, i.e., if table t1 is supposed to have two columns (say c1 and c3) and yamltodb finds three (c1, c2 and c3) and would have to issue I'm still not sure why you want this feature. By default, yamltodb does not update the database: it only shows the SQL needed to change it to match the input YAML spec. You have to use the If you want to control that a database hasn't changed from a master YAML spec, with the current Pyrseas tools, you could do two things:
If we add the |
I understand you, it's hard to show use cases to prove necessity of this flag, but roughly speaking it's sometimes quite usefull to get know, that database schema is changed towards given yaml schema. Also yamltodb command exit status <> 0 will be fine in automated deploy scripts ... Anyway, |
What would be very easy to add is to exit yamltodb with, say, exit status 2, if we wrote SQL statements, or status 0 if there were no schema diffs, i.e., no statements. If |
I've committed change 38772f2 which adds exits status 2 to indicate SQL statements were generated. I've also updated the yamltodb to highlight the exit statutes and the possible use of status 0 vs. 2. Please let me know if this satisfactory for your purposes. |
that's right, the only question why status 2 to indicate SQL statements were generated? As I know status <> 0 if for some failure cases |
Maybe I misunderstood your earlier comment. You wrote "Also yamltodb command exit status <> 0 will be fine in automated deploy scripts". I thought you wanted an exit status <> 0 to indicate a diff was present. Yamltodb is somewhat like the Unix diff command, except instead of diff'ing two files, you diff a representation of the database (the YAML spec) to another (the current catalogs). When diff doesn't find a difference between two files, its exit status is 0. When it does find a diff, the status is 1. When some other error occurs, e.g., file(s) not found, the status is 2. I was actually going to implement yamltodb statuses that way (and I can still do that), but it was easier (oh laziness :-) to exit with 2 for a diff. |
Let's I try some use case. Say, we want to apply schema to the current database, also we do it in automated process with chef recipe, if everything okay, the exit status of yamltodb command will be 0, if something goes wrong than it should return <> 0 exit status. The reasons why |
I've posted in the pyrseas-general ML: http://lists.pgfoundry.org/pipermail/pyrseas-general/2012-June/000053.html to see what others think. Feel free to subscribe and join the discussions. |
Ok. I give up here ((: I understand diffish approach, but if to think in way of automatic deployment it's not that fine, maybe it means that yamltodb is not for automatic deployment, we need some wrapper around it, anyway, exit status is not that critical if one run yamltodb manually. |
Please don't give up. I sort of convinced myself that "diffish approach", as you called it, would be OK for a tool named yamldbdiff, but not exactly for yamltodb which is supposed to generate SQL statements and even apply them to the database. yamldbdiff could be created as a simple wrapper around yamltodb if desired. So, I'll back out my exit status changes. The question then remains if there is anything else that you'd prefer to see done with this issue or whether I can close it. |
Change f96448e backs out the "exit with 2" change. |
Got thinking about the general issue of renaming objects in the database and how to capture info about such an action. Ideally, PG would be modified so that when someone issues An alternative would be for Pyrseas to provide a utility or extension through which ALTER RENAME commands could be issued and at the same time the info would be captured in a |
cat schema.yaml
yamltodb -H melezhik.x --user test -1 test test.yml | psql --user=test -h melezhik.x test
alter table t1 rename column c4 to cc4;
yamltodb -H melezhik.x --user test -1 test test.yml
which is wrong, because only drop column cc4, but also has to create column c4!
The text was updated successfully, but these errors were encountered: