PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Sự cố với phạm vi thời gian vô hạn trong Rails

Bạn không thể lưu trữ Infinity như một phần của phạm vi thời gian trong Rails. Tôi tin rằng điều này là do Infinity sẽ được chèn dưới dạng một giá trị chuỗi và được hiểu là một phao khi được kéo ra khỏi oid PSQL gốc. Vì vậy, bất kỳ phạm vi ngày nào từ Date -> Float sẽ không khả thi. Nhưng bạn có thể quản lý để tạo phạm vi của riêng mình với các ngày giả (1 triệu năm kể từ bây giờ) hoặc bạn chỉ có thể sử dụng hai trường ngày riêng biệt và diễn giải chúng một cách thích hợp trong mô hình. Ngày bắt đầu, ngày kết thúc.

Trong Rails 4.2+, bạn có thể lưu trữ giá trị Float ::INFINITY bên trong loại datetime của mình. Ví dụ.

User.first.update(begin_date: DateTime.now, end_date: 'infinity')
User.first.end_date # => Infinity

Tuy nhiên, end_date sẽ không phải là một ngày hợp lệ. Bạn chỉ đang lưu trữ chuỗi trong cơ sở dữ liệu và bạn đang lấy ra một float khi bạn gọi nó.

Đây là mã thực tế (Rails 4.2) xử lý điều đó:

module ActiveRecord
  module ConnectionAdapters
    module PostgreSQL
      module OID # :nodoc:
        class DateTime < Type::DateTime # :nodoc:
          include Infinity

          def type_cast_for_database(value)
            if has_precision? && value.acts_like?(:time) && value.year <= 0
              bce_year = format("%04d", -value.year + 1)
              super.sub(/^-?\d+/, bce_year) + " BC"
            else
              super
            end
          end

          def cast_value(value)
            if value.is_a?(::String)
              case value
              when 'infinity' then ::Float::INFINITY
              when '-infinity' then -::Float::INFINITY
              when / BC$/
                astronomical_year = format("%04d", -value[/^\d+/].to_i + 1)
                super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
              else
                super
              end
            else
              value
            end
          end
        end
      end
    end
  end
end

Một lần nữa, bạn sẽ không có thể so sánh thời gian ngày tháng với một float. Nhưng, nó có thể đủ đơn giản để có một trường hợp đặc biệt cho hai giá trị này -::Float::INFINITY::Float::INFINITY




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sự cố khi kết nối Pentaho Kettle / Spoon với Heroku PostgreSQL bằng SSL

  2. Có thể tự động lặp qua các cột của bảng không?

  3. Chỉ định duy nhất các điểm gần nhất giữa hai bảng

  4. Hibernate lạc quan khóa các hành vi khác nhau giữa Postgres và MariaDb

  5. Tại sao tất cả các cơ sở dữ liệu đều có một lược đồ công khai trong PostgreSQL?