-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Add support for specifying comments for tables, columns, and indexes in database itself #22911
Conversation
Thanks for the pull request, and welcome! The Rails team is excited to review your changes, and you should hear from @rafaelfranca (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
PostgreSQLColumn.new(name, default, sql_type_metadata, null, default_function, collation, comment) | ||
end | ||
|
||
def table_comment(table_name) |
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.
# :nodoc:
It looks good to me. I made some minor comments. Make sure you rebased and squased your commits and ping me when done. |
@rafaelfranca thanks for review. Fixed your notes, squashed, and rebased. |
@@ -703,6 +713,9 @@ def table_options(table_name) | |||
|
|||
# strip AUTO_INCREMENT | |||
raw_table_options.sub(/(ENGINE=\w+)(?: AUTO_INCREMENT=\d+)/, '\1') |
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.
sub
should be changed to sub!
as now this is not yet the return value and will be discarded otherwise.
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.
Oops, you're right! Fixed.
@rafaelfranca is there anything left for me to change? I rebased and squashed. |
require 'cases/helper' | ||
require 'support/schema_dumping_helper' | ||
|
||
class PostgresqlCommentTest < ActiveRecord::PostgreSQLTestCase |
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.
This looks a lot like the MySQL equivalent. Do we have precedent for that? Shouldn't this be a generic test, which just gets skipped on sqlite3?
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.
@matthewd is there example of such a generic test with exceptions for some adapters in ActiveRecord?
I have tried to make a single test here: Envek@0db3d7b#diff-b905e321f988197140400a200a951ec0
But for some reason these tests doesn't run for MySQL:
➜ activerecord ARCONN=mysql2 bundle exec ruby -Itest test/cases/comment_test.rb
Using mysql2
Run options: --seed 20982
# Running:
Finished in 0.001537s, 0.0000 runs/s, 0.0000 assertions/s.
0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
ActiveRecord::Base.connection.supports_comments?
at Envek@0db3d7b#diff-b905e321f988197140400a200a951ec0R29 returns true
PostgreSQL is fine:
➜ activerecord ARCONN=postgresql bundle exec ruby -Itest test/cases/comment_test.rb
Using postgresql
Run options: --seed 21355
# Running:
......
Finished in 1.961782s, 3.0584 runs/s, 11.7240 assertions/s.
6 runs, 23 assertions, 0 failures, 0 errors, 0 skips
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're still inheriting from PostgreSQLTestCase
.
See pretty much all the uses of current_adapter?
for relevant examples. (Notably, I think we generally don't use supports_*?
methods to decide whether the tests should run, because an incorrect result could cause the tests to be skipped instead of reporting the problem.)
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.
Uh, seems like I was really sleepy this morning. Sorry for wasteing your time. Fixed!
@rafaelfranca, @matthewd, I merged the tests into generic one, squashed and rebased. |
Does anything prevents this PR from being merged? :-) |
@connection.drop_table 'commenteds', if_exists: true | ||
end | ||
|
||
if %i[ Mysql2Adapter PostgreSQLAdapter ].any? { |a| current_adapter?(a) } |
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.
if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter)
@kamipo, thanks for review. Fixed your notes. Anything else? |
:options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options | ||
delegate :quote_column_name, :quote_table_name, :quote_default_expression, :quote, :type_to_sql, | ||
:options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options, | ||
:supports_comments?, :supports_comments_in_create?, to: :@conn |
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.
:supports_comments_in_create?
is unused in SchemaCreation
. And I think :supports_comments?
is not needed.
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.
Removed :supports_comments_in_create?
and :supports_comments?
from SchemaCreation
.
+1 for this |
@kamipo thank you for review and sorry for the delay. Fixed your notes. Is there anything that I should do? |
I want this feature. It seems that there are some conflicts with the current master. |
@kou, thank you for support. There were a lot of merge conflicts this time (usually it's only @kamipo, @rafaelfranca, what do you think? |
Comments are specified in migrations, stored in database itself (in its schema), and dumped into db/schema.rb file. This allows to generate good documentation and explain columns and tables' purpose to everyone from new developers to database administrators. For PostgreSQL and MySQL only. SQLite does not support comments at the moment. See docs for PostgreSQL: http://www.postgresql.org/docs/current/static/sql-comment.html See docs for MySQL: http://dev.mysql.com/doc/refman/5.7/en/create-table.html
@rafaelfranca Is there any chance to get it into 5.0? |
Add support for specifying comments for tables, columns, and indexes in database itself
@jeremy thank you for merging! |
Thank you @Envek! Very nice work, and thorough. I have a couple of tweaks coming. (Could be neat to explore: adding default comments in migrations so tables/columns/indexes indicate which migration added them.) |
Looks like we could support this for SQLite, too, since it records the SQL comments used in CREATE TABLE statement: http://stackoverflow.com/questions/6460671/sqlite-schema-information-metadata/6617764#6617764 |
As I can see from the links, SQLite only saves |
Oops, missed linking http://stackoverflow.com/questions/7426205/sqlite-adding-comments-to-tables-and-columns?lq=1 above too. We parse the SQL statement already to extract collation info. It's a little easier because we fetch columns first using Ditto for a table comment. If we have a |
@jeremy can you share and example for how "adding default comments in migrations" would look like. |
@vipulnsward Think of "git blame" but for your database schema. We'd see which migration last touched a table, column, or index. Maybe not the best use of comments, but a fun idea to explore. This could also be tracked in a separate metadata table, after all, but that wouldn't be visible in DBA tools. For example, # db/migrate/20160417165529_create_foobars.rb
# class CreateFoobars
create_table :foobars do |t|
t.string :name, index: true
end could result in a |
Got it. I am going to explore this. |
Refactor of rails#22911.
Why not just use |
Yeah, that's the fun part to explore, @marnen. A db comment indicates what's actually live in the database (authoritative source) vs. what's committed to the codebase (may be ahead of database). @vipulnsward implemented to try it out in #24622, but indeed it weighed a bit on the noisier side of helpful. |
Refactor of #22911. Signed-off-by: Jeremy Daer <jeremydaer@gmail.com>
@jeremy Since the |
Sure - why? For the fun of exploring an idea and using a new feature
|
Implemented by rails#22911 Related to rails#30677
Enabled specify comment of database objects is introduced at rails#22911. But for table comment, support only in the create_table clause, so cannot add or modify comment for the existing table. But add (modify) table comment is helpful to develop an app that getting complex as time proceeds, or maintaining a historic app.
This pull request adds support for specifying comments for database objects in migrations, storing them inside database, and dumping them into
db/schema.rb
file for PostgreSQL and MySQL.In my opinion it is really useful feature, allowing people to create documented data model right from Rails migrations. New people can look for tables, columns, and indexes meaning right in
db/schema.rb
(or right in model files with gems like @ctran's annotate_models) and DBA can view that information directly from MySQL Workbench, PgAdmin III, DBeaver or anything else. Afterwards any existing data modelling tool can be used to generate data model documentation (such as ER diagrams and table structure) automatically with minimal editing.For example in my work recently was situation when we were need to send documentation to customer and database schema was part of it. We lost a day helping writers to make this docs as we explained tables and table columns meaning only in our internal wiki (and it was incomplete because everyone always forgets to edit it when writing a migration) and writers came to us with autogenerated docs from our staging database. And there was a lot of manual docs merging and investigation.
Among built in adapters only PostgreSQL and MySQL supports it (SQLite does not). Also oracle_enhanced adapter supports comments with exactly same syntax (actually I follow it's syntax). May be @rsim, @yahonda, or @cdinger will also review and say whether I should change something for ease of integration of oracle_enhanced implementation with my implementation.
Comment implementation in RDBMS differs heavily:
COMMENT
command to set or delete comments on any database objects (like Oracle) and have no syntax to specify comments at time of creation or modification object. See docs: http://www.postgresql.org/docs/current/static/sql-comment.htmlCREATE TABLE
andALTER TABLE
commands and column and index definitions. No separate commands. See docs: http://dev.mysql.com/doc/refman/5.7/en/create-table.htmlHere ActiveRecord takes all dirty work and hides all differences between implementations. I think this is awesome.
Unfortunately I'm not really experienced in ActiveRecord hacking and most of the work I have done blindly, just by inserting code chunks here and there and seeing what errors will occur and whether tests will pass. Is there any docs about ActiveRecord internals and architecture? I would be glad to read them. Please review carefully and tell me what I should change. I think this PR should be considered as Work In Progress, hence it already do it's job well.
Also I think that note about importance of schema documentation should be added to guides, but can't imagine good place and good words for it (and my English really isn't good enough for guides yet). Any suggestions are welcome!