【问题标题】:How do you define postgres functions in Rails and what is their scope and lifetime?你如何在 Rails 中定义 postgres 函数,它们的作用域和生命周期是什么?
【发布时间】:2026-01-10 23:10:01
【问题描述】:

我对 Postgres 函数一无所知,但是最近出现了几次使用它们的需求(这可能表明我正在错误地处理问题,但无论如何......)

我想定义一个这样的 Postgres 函数,然后我将通过 Rails 应用程序中的查询访问它:

CREATE FUNCTION date_in_time_zone(time_zone) RETURNS date AS 
  'SELECT DATE(NOW() AT TIME ZONE time_zone);' 
  LANGUAGE SQL; 

(来自this question)。

问题第 1 部分:如何定义此函数?

我想我会这样做:

sql = "CREATE FUNCTION date_in_time_zone(time_zone) RETURNS date AS 
       'SELECT DATE(NOW() AT TIME ZONE time_zone);' 
       LANGUAGE SQL;"
ActiveRecord::Base.connection.execute sql

这对吗?

问题第 2 部分:这个函数的作用域和生命周期是什么?

一旦定义,此功能将持续多长时间以及管理该功能版本控制的最佳方式是什么。如果它是在数据库而不是 Rails 中定义的,那么如果我想改变它的工作方式,我将不得不小心地销毁它或更新它。每次加载 Rails 环境时,我还需要一些方法来初始化函数。

我应该在应用程序初始化时创建一次函数,还是需要为每个 Web 请求创建函数?我认为前者是在数据库中定义的,但我不确定。

问题第 3 部分:我是否应该使用这种方法?

这只是个坏主意吗?我应该尝试以不同的方式解决问题吗?我真的不知道这些函数的作用域或生命周期是什么。

【问题讨论】:

    标签: ruby-on-rails postgresql timezone


    【解决方案1】:

    一旦创建,PostgreSQL 中的函数就会永久持久化。与其他对象一样,它位于架构中,并且仅当此架构位于您当前会话的 search_path 中时才能找到。

    在通用数据库中,您可以在默认的 schema public 中创建函数。在更复杂的设置中,您可能有一个专用的函数模式或每个用户的专用模式。 search_path 将被相应地设置。

    使用CREATE OR REPLACE FUNCTION ... 而不仅仅是CREATE FUNCTION ...,这样您就可以替换现有函数的主体(无需更改IN 或OUT 类型)。在最近的answer by @Pavel Stehule on dba.SE 中了解更多信息。

    注意时区名称缩写或数字偏移量的略微不同的影响。相关问题/答案:
    Time zone names with identical properties yield different result when applied to timestamp
    PostgreSQL - how to render date in different time zone?

    【讨论】:

    • 除了 Rails 方法之外,您是否建议使用 Postgres 函数?我知道我可能会回到这里的一条坏巷。根据您的经验,是否应该无需创建数据库函数就可以解决这些类型的问题,还是不可避免地需要深入研究?
    • 我不是 Postgres 方面的专家,更不是 Rails 方面的专家。您的附加问题的答案很大程度上取决于很多细节。
    最近更新 更多