使用 SQLite 的特定于分支机构的数据库
liebian365 2024-11-13 13:24 29 浏览 0 评论
这是一系列帖子中的第一篇,我想重点介绍增强 Ruby on Rails 应用程序的方法。 具体来说,在第一个系列中,我想深入探讨我们可以利用和授权使用 SQLite 作为 Rails 应用程序的数据库引擎的方法。 在这篇首篇文章中,让我们深入探讨如何使用 SQLite 作为我们的数据库引擎为我们的本地开发工作流程开辟强大的新可能性; 具体来说,允许我们拥有并使用特定于部门的数据库。
过去几年,人们对在 Web 应用程序生产中使用 SQLite 的兴趣激增。 我欣然承认我也完全同意。 SQLite 消除了网络延迟,简化了操作,并使针对生产堆栈的自动化测试变得容易。
在本系列的整个过程中,我想介绍一些我们可以对 Rails 应用程序进行的关键调整,以使 SQLite 的使用更加强大和愉快。 首先,我想重点关注本地开发的开发人员体验 (DX) 改进。
任何在开发团队中开发过 Rails 应用程序的人都知道,管理数据库模式可能很棘手。 每个开发人员的分支可能包括一些迁移,这些迁移会更新架构,但在本地您只有一个开发数据库。 在分支之间切换变得很痛苦,运行迁移也变得很痛苦,有时,当模式更改被合并时,错误会潜入生产中,而这些更改本来不应该成为该版本的一部分。
我最喜欢的 PlanetScale 功能之一是其分支功能:
分支是数据库模式的副本,它们存在于彼此完全独立的环境中。 在一个分支中进行更改不会影响其他分支,直到您合并它们,就像管理项目中的代码分支一样。
这很可爱,它解决了上面列出的痛点。 然而,在我看来这并不十分完美。 因为我们的应用程序现在有两种不同类型的“分支”。 我们有 Git 分支,它隔离我们的代码(包括迁移),还有我们的数据库分支,它隔离我们的模式。 现在拥有两个独立的分支会产生同步问题。 Git 分支和数据库分支如何关联? 我们如何将 git 分支合并与数据库分支合并与生产部署联系起来? ETC。
这是 PlanetScale 需要做出的必要权衡,因为他们的无服务器数据库平台无法与每个用户的代码库深度集成。 然而,作为使用 SQLite 的 Rails 开发人员,我们拥有独特的机会。
让我们描述一下我们的理想场景,然后深入研究如何实现它。 我们想要的是有一个单独的分支(Git 分支)来隔离我们的代码和模式。 我们希望切换 Git 分支来自动切换模式分支。 我们希望生产部署由 Git 分支合并驱动,同时还能自动确保可预测且稳定的生产模式。 听起来不错,不是吗? 幸运的是,Rails 和 SQLite 使这样的设置非常容易创建。
让我们从最后一个功能开始,因为这是 Rails 为我们提供的功能,无论我们的数据库引擎如何。 这个功能正是我们的 /migrations 目录和 /db/schema.rb 或 /db/struction.sql 文件的值。 通过将数据库模式管理集成到 Rails 应用程序代码库中,并确保所有模式更改都是通过 Rails 迁移实现,我们可以将生产模式绑定到简单的 Git 分支合并,同时还确保我们的生产模式是可预测的和稳定的。
老实说,其他两个功能也可以通过任何 Rails 支持的数据库适配器实现,但 SQLite 最适合这种方法。 而且方法很简单。 从根本上来说,我们需要做的就是告诉 Rails 使用与 Git 分支名称绑定的动态数据库名称进行本地开发。 Rails 通过 /config/database.yml 文件使这变得容易,这是我们配置数据库核心细节的地方。 默认情况下,当使用 SQLite 时,Rails 会生成一个 /config/database.yml ,如下所示:
# SQLite. Versions 3.8.0 and up are supported.
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem "sqlite3"
#
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
development:
<<: *default
database: storage/development.sqlite3
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: storage/test.sqlite3
production:
<<: *default
database: storage/production.sqlite3
简单合理。 每个 Rails 环境都有自己的数据库文件。 每个数据库文件都存储在 /storage 目录中(大多数托管提供商确保内容在部署中保留)。 并且每个数据库文件都有一个固定的文件名。 我们想要的是让我们的开发环境使用数据库的动态文件名,并且我们希望该文件名基于当前的 Git 分支。 快速谷歌搜索会得到一个 StackOverflow 答案,它提供了用于获取当前分支名称的 git 命令:
git branch --show-current
注意:如果您使用的 Git 版本低于 2.22(添加了 --show-current 选项时),您可以使用 git rev-parse --abbrev-ref HEAD 代替。
那么,我们如何在 /config/database.yml 文件中使用它呢? 嗯,Rails 使这一切变得简单,因为它允许 ERB。 为代码添加一点弹性,我们可以用以下内容替换我们的开发部分:
development:
<<: *default
database: storage/<%= `git branch --show-current`.chomp || 'development' %>.sqlite3
现在,我们不再总是使用 storage/development.sqlite3 作为数据库文件名,而是提供一个动态文件名,无论我们当前的 Git 分支名称是什么,该文件名都会命名数据库文件。 通过这一行更改,我们实现了第一个理想功能——我们有一个分支(Git 分支),它隔离了我们的代码和模式。
接下来,我们如何配置Rails在我们的Git分支发生变化时自动切换“模式分支”? 好吧,根据上面的解决方案,我们需要更清楚地阐明我们到底需要什么。 对 /config/database.yml 文件的更改已经确保了当我们切换 Git 分支时,我们的 Rails 应用程序将与隔离的开发数据库进行通信。 然而,仅此更改并不能确保一旦我们切换了 Git 分支,我们的独立开发数据库就可以使用了。 想象一下,一位同事创建了一个分支,添加了两个新的数据库迁移。 您拉下该分支来进行一些代码审查和本地手动测试。 当您第一次切换本地 Git 存储库以签出同事的分支时,我们的动态 /config/database.yml 配置将确保在 /storage 目录中创建新的 SQLite 数据库文件。 但是,这个新的 SQLite 数据库文件中还没有任何内容,也没有架构设置。 那么,我们如何确保每当我们切换数据库分支时Rails都会自动准备这个新的数据库文件呢?
好吧,对我们来说幸运的是,Rails 使这变得非常简单。 Rails 提供了 ActiveRecord::Tasks::DatabaseTasks 实用程序类,它“封装了用于管理数据库和迁移的常见任务背后的逻辑”。 根据我们的需要,我们可以使用 .prepare_all 方法,该方法相当于 Rails 6 中添加的 db:prepare Rake 命令。准备数据库意味着,如果数据库已经存在,则运行迁移,或者创建数据库并加载 如果没有,则为架构。 我们需要做的就是告诉 Rails 在开发中每次启动应用程序时运行此命令。 这将确保我们的动态数据库始终可供我们的 Rails 应用程序使用(无论是运行服务器还是跳转到控制台)。
为了让 Rails 在启动应用程序时在开发中运行此命令,我们只需将其添加到 /config/environments/development.rb 文件中:
# Ensure that our branch-specific SQLite database is prepared for our application to use
config.after_initialize do
ActiveRecord::Tasks::DatabaseTasks.prepare_all
end
我们只需配置开发环境以在应用程序初始化后运行 .prepare_all 命令。
添加了这个简单的配置,我们现在有了理想的设置。 每个 Git 分支都有自己独立的数据库文件。 当我们启动 Rails 应用程序时,该数据库会自动准备好供按需使用。 由 Git 分支合并驱动的生产部署通过专门使用迁移来改变我们的模式,继续产生稳定且可预测的生产模式。
我可以说,我已经在几个不同的 Rails 应用程序中使用了这个设置,我非常喜欢它! 我喜欢 Rails 和 SQLite 如此轻松地设置这样的功能。 总共有四行(如果我们使用 after_initialize 的内联块,很容易就变成两行),为像 PlanetScale 这样的奇特平台提供类似的(并且在某些关键方面有所改进)功能。
相关推荐
- 4万多吨豪华游轮遇险 竟是因为这个原因……
-
(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...
- “菜鸟黑客”必用兵器之“渗透测试篇二”
-
"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...
- 科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白
-
作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...
- 麦子陪你做作业(二):KEGG通路数据库的正确打开姿势
-
作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...
- 知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势
-
智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...
- 每日新闻播报(September 14)_每日新闻播报英文
-
AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...
- 香港新巴城巴开放实时到站数据 供科技界研发使用
-
中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...
- 5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper
-
本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...
- Qt动画效果展示_qt显示图片
-
今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...
- 如何从0到1设计实现一门自己的脚本语言
-
作者:dong...
- 三年级语文上册 仿写句子 需要的直接下载打印吧
-
描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...
- C++|那些一看就很简洁、优雅、经典的小代码段
-
目录0等概率随机洗牌:1大小写转换2字符串复制...
- 二年级上册语文必考句子仿写,家长打印,孩子照着练
-
二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)