英文:
How to validate schema.rb file in rails for any syntax errors?
问题
We have two different apps and both are dependent on each other's database for running the tests.
For example, we create 'App2's DB before running the specs in 'App1' using the 'App2' - 'schema.rb'.
The issue here is that there have been a few scenarios where we faced syntax issues like 'Mysql2::Error: You have an error in your SQL syntax;' while creating the 'App2' SQL structure in 'App1's test using the 'schema.rb'.
So, I was thinking is there any way to verify the 'schema.rb' in 'App2' after someone has updated it? So that we never face any issues while creating the structure in 'App1'.
英文:
We have two different apps and both are dependent on each other's database for running the tests.
For example, we create App2
's DB before running the specs in App1
using the App2
- schema.rb
.
The issue here is that there have been a few scenarios where we faced syntax issues like Mysql2::Error: You have an error in your SQL syntax;
while creating the App2
SQL structure in App1
's test using the schema.rb
.
So, I was thinking is there any way to verify the schema.rb
in App2
after someone has updated it? So that we never face any issues while creating the structure in App1
.
答案1
得分: 3
假设你的 schema.rb
只包含 Ruby 代码而不是原始 SQL,你可以安全地使用 Rubocop 进行验证:
rubocop db/schema.rb
或者,你也可以使用 ruby
来完成相同的任务:
ruby -c db/schema.rb
然而,在你的帖子中有两点让我怀疑你可能有原始 SQL:
- 错误信息
Mysql2::Error: You have an error in your SQL syntax
- 引用的 “the App2 SQL structure”,这可能意味着你实际上在导出 SQL 结构
如果你使用了原始 SQL,你可能需要考虑使用 SQL 语法检查工具,比如 sqlfluff,它可以对原始 SQL 进行类似 Rubocop 的检查:
sqlfluff lint db/structure.sql
另外,你可以在测试套件中添加一个步骤,使用 schema 删除并重新创建测试数据库,以确保测试套件运行时验证 schema:
bundle exec rails db:drop db:create db:schema:load db:migrate
你可以在一个或两个应用的测试套件中运行此命令,以确保 schema 的正常工作。
最后,你应该确保只通过 ActiveRecord migrations 进行 schema 的更改;不要直接编辑 schema 文件,确保它只通过 migrations 进行更新。
英文:
Assuming that your schema.rb
contains only Ruby code and not raw SQL, you can likely safely validate it with Rubocop:
rubocop db/schema.rb
Alternatively, you can use ruby
to do the same:
ruby -c db/schema.rb
However two things in your post indicate to me that you may have raw SQL:
- The error
Mysql2::Error: You have an error in your SQL syntax
- The quote "the App2 SQL structure" which may indicate that you're actually dumping the SQL structure
If you have raw SQL then you may want to consider a SQL linter like sqlfluff which can do the same thing that Rubocop does but for raw SQL:
sqlfluff lint db/structure.sql
Alternatively, you can integrate a step in your test suite that deletes and recreates the test database using the schema to ensure that when the test suite runs it validates the schema:
bundle exec rails db:drop db:create db:schema:load db:migrate
You can run this in one or both of the apps' test suites to ensure that the schema is working as expected.
Finally, you should ensure that changes to the schema are only ever made through ActiveRecord migrations; don't edit the schema file directly and ensure that it only updates via migrations.
Additional advice based on the comments conversation below
If your schema is even slightly complex or includes any raw SQL or Arel commands then use the SQL schema dump option instead to generate raw SQL:
> When the schema format is set to :sql
, the database structure will be dumped using a tool specific to the database into db/structure.sql
. For example, for PostgreSQL, the pg_dump
utility is used. For MySQL and MariaDB, this file will contain the output of SHOW CREATE TABLE
for the various tables.
This will mean that your schema is managed in db/structure.sql
instead of db/schema.rb
going forward.
First, add this to config/application.rb
:
config.active_record.schema_format = :sql
Next, dump your schema using the following command:
bundle exec rails db:schema:dump
As described above, you can load this schema using:
bundle exec rails db:schema:load
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论