首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Rails 迁移(1)

Rails 迁移(1)

目前,持久性框架使用两种方法中的一种:   映射   或   包装   。映射解决方案允许创建独立的数据库模式和对象模型,然后用一个软件层来管理两者间的差异。映射解决方案试图构建一个与数据库模式的结构非常相似的对象模型。与之相反,包装解决方案用对象作为数据库表和行的包装器来操纵数据库中的数据。常规的想法认为在解决方案发布之后,映射解决方案通常更灵活,因为映射软件能够更好地处理模式或对象模型中的变化。但是这个想法忽略了其中最重要的部分:数据。要有效地管理涉及持久性域模型的应用程序变化,必须协调数据、模式和模型的变化。大多数项目团队做不到这一点。   
  开发团队处理模式变化时,通常会用 SQL 脚本从头开始生成一个新版模式。脚本可能会删除所有的表,再添加所有的表。这样的策略会破坏所有测试数据,因此对于生产场景来说毫无价值。偶尔,工具可能会创建脚本,由脚本生成 delta 模式,或者生成使用   alter_table   这样的 SQL 命令修改以前版本的模式。但是很少有团队会费力气创建能取消模式变化的脚本,而且成功地创建了处理数据变化的自动脚本的团队更少。简而言之,传统的映射策略忽略公路上的汽车:回退坏的模式变化并处理数据。   
关于这个系列  在   系列中,作者 Bruce Tate 倡导这样一个概念:今天的 Java 程序员可以通过学习其他方式和语言而受益。在编程领域中,Java 技术是所有开发项目的最佳选择的情况已经变了。其他框架正在影响 Java 框架的构建方式,从其他语言学到的概念有助于 Java 编程。编写的 Python(或 Ruby、Smalltalk 等等)代码可以改变 Java 编码的方式。   
这个系列介绍了与 Java 开发有根本不同,但是却直接适用于 Java 开发的编程概念和技术。在某些情况下,需要集成这些技术以利用它们。在其他情况下,可以直接应用这些概念。其他语言和框架能够影响 Java 社区的开发人员、框架甚至基本方式,与此相比,单独的工具并不那么重要。

  这篇文章深入研究了 Ruby on Rails 迁移 —— Rails 处理生产数据库变化的解决方案。迁移用包装的方式组合了协调模式变化和数据变化的威力和简单性。(如果以前没有学习过活动记录 —— Rails 底层的持久性层,我建议您先阅读   跨越边界   系列中以前的这篇 Rails    。)   
在 Java 编程中处理模式变化基于映射的框架需要模式、模型和映射。这样的框架是重复性的。请想像一下指定一个属性需要重复多少次:
  • 模型中的 getter
  • 模型中的 setter
  • 模型中的实例变量
  • 映射的 “to” 端
  • 映射的 “from” 端
  • 列定义
公平地讲,Hibernate 这样的 Java 框架通过代码生成的方式消除了不少重复工作。对象关系映射器可以处理遗留模式,对于新的数据库模式,可以用 Hibernate 提供的工具直接从模型生成模式并用 IDE 生成 getter 和 setter。可以用 Java 标注把映射嵌入域模型,但是按我的观点,这在一定程度上违背了使用映射的初衷。这种代码生成技术还有另一个用途:模式迁移。有些代码生成工具可以发现新的域模型和旧的模式之间的区别,并生成沟通这些不同的 SQL 脚本。请记住这些脚本处理的是模式,而不是数据。
  例如,考虑这样一个迁移:把   first_name   和   last_name   这两个数据库列合并成叫作   name   的单一列。来自典型 Java 持久性框架的工具对数据库管理员没有帮助,因为这些工具只处理问题的一部分:模式中的变化。在进行这个模式变化时,还需要能够处理现有数据。在需要部署这个假想应用程序的新版本时,数据库管理员通常必须手工创建 SQL 脚本来完成以下工作:   
  •   创建叫作   name   的新列。
  •   把   first_name   和   last_name   的数据放到新列中。
  •   删除   first_name   和   last_name   列。
如果造成模式变化的代码版本仍然处在不完善的状态,那么经常必须手工回退变化。只有很少的团队有这个素养可以集成并自动进行跨模型、模式和数据的变化。
Rails 迁移基础在 Rails 中,所有模式变化 —— 包括模式最初的创建 —— 都在迁移中发生。数据库模式中的每个变化都有自己的迁移对象,迁移对象包装了前进和后退。清单 1 显示了一个空迁移:
清单 1. 空迁移
1
2
3
4
5
6
7
class EmptyMigration < ActiveRecord::Migration
  def self.up
  end

  def self.down
  end
end




  我很快将介绍如何调用迁移,但是现在请看看清单 1 中的迁移结构。在这个迁移的   up   方法中,要放置进行一个逻辑数据库变化所需的全部代码。还要捕获任何变化,从而能够取消模式变化。通过封装   up   和   down   ,Rails 开发和生产工具可以自动进行涉及持久性对象模型的变化的部署和回退过程。这些数据库变化可能包括:   
  通过封装   up   和   down   方法,Rails 开发和生产工具可以自动进行涉及持久性对象模型的变化的部署和回退过程。   

  • 添加或删除新表。
  • 添加或删除新列。
  • 以其他方式修改数据库,包括添加、删除或修改索引或其他约束。
  • 修改数据库数据。
通过允许改变数据,迁移大大简化了相关数据和模式的变化的同步过程。例如,可以添加一个查询表,把每个州和州的两位数字 ZIP 代码关联起来。在迁移中,可以填充数据库表,可能通过调用 SQL 脚本或装载 fixture。如果迁移正确,那么每个迁移都会把数据库置于一个一致的状态,不需要手工干预。
每个迁移的文件名都以一个惟一的编号开头。这个约定让 Rails 可以对迁移实现很强的排序。用这个策略,可以前后转移到逻辑数据库模式的任何状态。
返回列表