1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
= New Features
* A forbid_lazy_load plugin has been added to forbid the lazy loading
of model associations if the current object was retreived with other
objects. This plugin helps detect N+1 query issues. This plugin
will raise an error if a lazy load is detected in such cases:
Album.plugin :forbid_lazy_load
Album.one_to_many :tracks
Album.each do |album|
album.tracks
# Could be N+1, raises Sequel::Plugins::ForbidLazyLoad::Error
end
Album.first.tracks
# Could not be N+1, no error raised
The forbid_lazy_load plugin is designed to be loaded into the base
model class (generally Sequel::Model), and can be loaded only in
test mode, or only in certain test mode configurations, so that it
does not have any production performance impact.
Note that an alternative approach that Sequel has supported for many
years is the tactical_eager_loading plugin, which automatically
eager loads when an N+1 query issue is detected.
* An association_lazy_eager_option plugin has been added which supports
the :eager option for the association method. If the association has
not been loaded, this eagerly loads the associations specified by the
:eager option when loading the association. If the association has
already been loaded, this option is ignored, with the assumption that
whatever loaded the association already used the correct eager
loading. Example:
Album.plugin :association_lazy_eager_option
Album.one_to_many :tracks
Track.many_to_one :artist
album = Album.first
album.tracks(:eager=>:artist)
# Loads tracks for album, then artist for each track (2 queries)
album.tracks(:eager=>:artist)
# No query issued as association is cached
You could previously have similar behavior for uncached associations
by passing a block to the association method and calling eager on
the yielded dataset. However, that would ignore any cached
association, causing redundant loading of the association in such
cases.
* On PostgreSQL 10+, creating partitioned tables and partitions of
other tables is now supported.
To create a partitioned table, use the :partition_by option:
DB.create_table(:table1, partition_by: :date_column,
partition_type: :range) do
Integer :id
Date :date_column
end
DB.create_table(:table2, partition_by: :string_column,
partition_type: :list) do
Integer :id
String :string_column
end
DB.create_table(:table3, partition_by: :int_column,
partition_type: :hash) do
Integer :id
Integer :int_column
end
To add partitions of other tables, use the :partition_of option.
This option will use a custom DSL specific to partitions of other
tables.
For range partitioning, you can use the from and to methods to
specify the inclusive beginning and exclusive ending of the range
of the partition. You can call the minvalue and maxvalue methods
to get the minimum and maximum values for the column(s) in the
range, useful as arguments to from and to:
DB.create_table(:table1a, partition_of: :table1) do
from minvalue
to 0
end
DB.create_table(:table1b, partition_of: :table1) do
from 0
to 100
end
DB.create_table(:table1c, partition_of: :table1) do
from 100
to maxvalue
end
For list partitioning, you use the values_in method. You can also
use the default method to mark a partition as the default partition:
DB.create_table(:table2a, partition_of: :table2) do
values_in 1, 2, 3
end
DB.create_table(:table2b, partition_of: :table2) do
values_in 4, 5, 6
end
DB.create_table(:table2c, partition_of: :table2) do
default
end
For hash partitioning, you use the modulus and remainder methods:
DB.create_table(:table3a, partition_of: :table3) do
modulus 3
remainder 0
end
DB.create_table(:table3b, partition_of: :table3) do
modulus 3
remainder 1
end
DB.create_table(:table3c, partition_of: :table3) do
modulus 3
remainder 2
end
* On PostgreSQL 12+ and SQLite 3.31+, column schema hashes now have
a :generated entry for whether the column is a generated column.
* The schema_dumper extension now dumps generated columns correctly
when using the :same_db option on PostgreSQL 12+.
* A skip_saving_columns plugin has been added. This allows skipping
saving of specific columns for the model. By default, it skips
saving of generated columns, but you can customize the columns
that it skips:
Album.plugin :skip_saving_columns
Album.skip_saving_columns = [:some_column]
= Other Improvements
* The alter_table drop_constraint :primary_key option on SQLite now
works correctly for non-integer primary keys.
* When an error is raised due to an irreversible migration, the error
message now includes the file containing the migration for easier
debugging.
|