`
darkbaby123
  • 浏览: 104077 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Rails和PostgreSQL -- 为指定的schema写migration文件

阅读更多

估计很多人看到标题都不知道是什么意思 。我也实在想不到比较清晰的标题……

 

当Rails和PostgreSQL碰到一起时,schema的意思就变得非常模糊了。对Rails而言,schema就是数据库的结构,实际上对大多数的数据库而言也是这样。而PostgreSQL中的schema指的是数据库和数据库对象(表,序列等)中间的一层,我也不知道翻译过来该叫什么,但pgAdmin中把这东西叫“模式”。用过PostgreSQL的同学应该不会陌生。下面的内容中,我会统一地把PostgreSQL中的schema叫做“模式”。

 

这篇文章,说的就是如何写这么一个迁移文件 -- 在指定的模式中进行操作,如创建表。比如以下代码的作用,就是在project模式下创建users表。

 

# config/initializers/migration_ext.rb
class CreateProjectTables < ActiveRecord::Migration
  def self.up
    run_in_schema :project do
      create_table :users do |t|
        t.string      :login
      end
    end
  end
end

 

这段代码和普通的migration文件没有什么区别,只是在create_table的外层加了一个run_in_schema而已。这样,users表就不是创建在默认的public模式,而是project模式。

 

run_in_schema在这里做了两件事:

  1. 如果数据库中没有project模式,则创建project模式。
  2. 让block中执行的所有操作(建表,执行指定sql语句等)都只影响project模式(这不是绝对的,下面会说明)。

run_in_schema的代码如下:

 

class ActiveRecord::Migration
  def self.run_in_schema(schema, &block)
    schema = schema.to_s
    
    # 如果没有该schema,就创建一个
    schemas = select_values "SELECT * FROM pg_catalog.pg_namespace WHERE nspname <> 'information_schema' AND nspname NOT LIKE 'pg%'"
    execute "CREATE SCHEMA #{schema}" unless schemas.include?(schema)

    # 设置一下search_path,让建表操作优先在指定的schema内执行
    re = execute "SHOW search_path"
    execute "SET search_path TO #{schema}, #{re.result}"
    yield
    execute "SET search_path TO #{re.result}"
  end
end

 

代码很简单,关键就在于search_path的设置。它把指定的模式(本文例子中的project)放在前面,后面才是原来的search_path。

但这样做有个问题。比如这段代码:

 

run_in_schema :project do
  drop_table :categories
end

 

这是一个删除categories表的操作。如果此时project模式中没有该表,但public模式中有的话,则会删除public模式下的categories表。原因就在于search_path中还是有public模式,只是搜索顺序靠后了一点。

 

那修改search_path的时候,只加入project模式不就完了?之所以不这样做,完全是因为schema_migrations这个表。Rails在执行完每一个migration文件后,都会去更新schema_migrations表。如果找不到,就会抛出异常。所以我不得不把原来的search_path加在进去。这个小bug只要稍加注意,还是没什么问题的。如果有同学知道这个问题的解决方法,请赐教。

 

参考资料

 

Creating a multi-tenant application using PostgreSQL's schemas and Rails

本来我是想找找Rails中怎么判断数据库中一个模式是否存在的方法的,然后在这篇文章中找到了解决办法,然后发现他设置search_path的思路和我一样,直接取消了我发到原创博客的想法……

分享到:
评论
1 楼 orcl_zhang 2010-09-16  
《Rails高级编程》的作者一直推荐用PostgreSQL。一直没有尝试过PostgreSQL,看到关于PostgreSQL也就带过了。
你们公司用PostgreSQL?

相关推荐

    guardrails-engine-output-schema-validator:GuardRails引擎的模式验证器

    guardrails-engine-output-schema-validator --help Usage: guardrails-engine-output-schema-validator [options] Options: -V, --version output the version number -s, --stdin Read from stdin -f, --file...

    rails-dev-box, 面向 Ruby on Rails 核心开发的虚拟机.zip

    rails-dev-box, 面向 Ruby on Rails 核心开发的虚拟机 用于 Ruby on Rails 核心开发的虚拟机简介注意:这个虚拟机不是为 Rails 应用程序开发而设计的,只是为。 这个项目自动设置开发环境,以便在 Ruby on Rails ...

    rails-documentation-1-2-1.zip

    标题 "rails-documentation-1-2-1.zip" 暗示这是一份关于 Ruby on Rails 框架的文档,版本为 1.2.1。Ruby 是一种面向对象的编程语言,而 Rails 是一个基于 Ruby 的开源 Web 应用程序框架,遵循 Model-View-...

    rails-development-environment-master.rar

    压缩包中的"rails-development-environment-master.zip"可能是整个项目文件夹,包括`app`(应用代码)、`config`(配置文件)、`db`(数据库相关)、`bin`(可执行脚本)、`lib`(自定义库)、`test`(测试)、`...

    rails应用--导航栏实例工程

    在本项目"rails应用--导航栏实例工程"中,我们将探讨如何在Ruby on Rails框架下构建一个实用的导航栏。Rails是一个流行的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,使得开发过程更加高效且结构...

    rails-passenger-postgres-ubuntu:在没有RVM或rbenv的Ubuntu 14.04上的Rails,PostgreSQL带Passenger + Nginx

    scp rails-passenger-postgres-nginx root@SERVER:/root/rails-passenger-postgres-nginx ssh root@SERVER "./rails-passenger-postgres-nginx app_name db_pass" 如果出现错误“ No PostgreSQL clusters exist ...

    rails-documentation-2-0-2

    rails-documentation-2-0-2

    rails-beginner-s-guide

    rails-beginner-s-guide是Rails 指导手册,帮组学习了解rails开发

    sclo-ror42-rubygem-rails-html-sanitizer-1.0.3-1.el7.noarch.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    rails-react-components-源码.rar

    在"rails-react-components-源码"中,我们可以看到如何定义React组件,以及如何通过props传递数据和方法。组件化开发提高了代码的可读性和可维护性,降低了复杂性。 2. **Webpack与Rails的集成** Rails默认使用...

    关于rails 3.1 cucumber-rails 1.2.0

    Rails 3.1 和 Cucumber-Rails 1.2.0 是两个在Web开发领域非常重要的工具,尤其对于Ruby on Rails框架的测试和自动化流程。本文将深入探讨这两个组件,以及它们如何协同工作来增强软件开发的效率和质量。 首先,...

    rails-chm-2-0-2.rar

    `rails-documentation-2-0-2.chm` 文件详细涵盖了这些概念,包含了关于Rails 2.0.2的API参考、教程和指南。通过仔细阅读和实践,开发者能够深入理解Rails的工作原理,并有效地开发出高效、可维护的Web应用。

    Ruby on Rails Guides v2 - Ruby on Rails 4.2.5

    ### Ruby on Rails Guides v2 - Ruby on Rails 4.2.5 #### 一、重要概念及基础假设 - **重要概念**:本指南旨在帮助...随着对Rails的深入了解,你将会发现更多高级特性和应用场景,为实际项目开发提供更多可能性。

    rails-dev-box:用于Ruby on Rails核心开发的虚拟机

    用于Ruby on Rails核心开发的虚拟机 介绍 请注意,该虚拟机并非为...host $ cd rails-dev-box host $ vagrant up 而已。 安装完成后,您可以使用以下命令访问虚拟机: host $ vagrant ssh Welcome to Ubuntu 20.10

    rails-documentation-1-2-0-rc1.chm

    rails-documentation-1-2-0-rc1.chm

    rails-yelp-mvp-源码.rar

    在描述中,"rails-yelp-mvp-源码.rar" 提示这是一个压缩文件,包含了构建一个Yelp类似功能的Web应用的全部源代码。通常,这样的项目会包含模型(Models)、视图(Views)和控制器(Controllers),以及数据库迁移...

    rails-ftw-v0.18-2.1.5-4.1.8

    rails-ftw-v0.18-2.1.5-4.1.8.exe用于在windows环境下搭建readmine环境

    rails-4.2.0-gems

    总的来说,Rails 4.2.0和Ruby 4.2.0的组合为开发者提供了强大而稳定的开发平台,而`rails_setup`文件则是一个宝贵的资源,帮助开发者快速搭建和配置环境。通过学习和理解这些知识点,开发者可以更高效地利用Rails...

    rails-playlists-源码.rar

    在"rails-playlists-源码"中,我们可能会看到代表播放列表和歌曲的ActiveRecord模型。 3. **路由(Routing)** Rails的路由系统将HTTP请求映射到控制器的特定动作上。在`config/routes.rb`文件中,开发者定义了URL...

    rails-exporter-源码.rar

    3. 文件生成与下载:Rails 内置的 send_data 和 send_file 方法可用于在服务器端生成文件后发送到客户端下载。 五、源码学习步骤 1. 阅读项目 README 文件,了解基本用法和安装步骤。 2. 分析 models 文件,理解...

Global site tag (gtag.js) - Google Analytics