On Fri, Jul 29, 2022 at 5:20 AM Pierre Yager <[email protected]>
wrote:

> Hello,
>
> I'm somewhat new to sequel (but not in Ruby nor Rails/ActiveRecord). I'm
> building an API based on geonames datasets.
>
> I want to export a subset of the country_info table :
>
> create table country_info
> (
>   iso_alpha2 char(2) not null constraint pk_iso_alpha2 primary key,
>   iso_alpha3 char(3),
>   iso_numeric integer,
>   fips_code text,
>   country text,
>   capital text,
>   area double precision,
>   population integer,
>   continent char(2),
>   tld text,
>   currency_code char(3),
>   currency_name text,
>   phone text,
>   postal text,
>   postal_regex text,
>   languages text,
>   geoname_id integer
>   neighbours text,
>   equivalent_fips_code text,
>   flag char(2) generated always as ((
>    chr((ascii("substring"((iso_alpha2)::text, 1, 1)) + (
> '00011111000110100101'::"bit")::integer)) ||
>    chr((ascii("substring"((iso_alpha2)::text, 2, 1)) + (
> '00011111000110100101'::"bit")::integer)))) stored
> );
>
> But I want to rename thr iso_alpha2 field into "code" and the country
> field into "name" and parse the neighbours field that contains a list of
> neighbours countries separated by commas (LU, BE, ES, IT, CH, ...)
>
> This is were I ended (written as a single file, without sinatra) :
>
> require 'sequel'
> require 'pg'
> require 'json'
>
> Sequel::Model.plugin :json_serializer
>
> DB = Sequel.connect('postgres://user:password@localhost/geonames')
> DB.extension :pg_array
>
> class Country < Sequel::Model(:country_info)
> # def_column_alias :code, :code
> # def_column_alias :name, :name
> end
>
> output = Country.select(
>  Sequel[:iso_alpha2].as(:code), Sequel[:country].as(:name),
>  :continent,
>  :postal, :postal_regex,
>  :geoname_id,
>  Sequel.function(:string_to_array, :neighbours, ',').as(:neighbours),
>  :flag
> ).to_json
>
> p output
>
> This code crash with this error :
>
> .../sequel-5.58.0/lib/sequel/plugins/json_serializer.rb:333:in `block in
> to_json': undefined method `code' for #<Country @values={:code=>"AD",
> :name=>"Andorra", :continent=>"EU", :postal=>"AD###",
> :postal_regex=>"^(?:AD)*(d{3})$", :geoname_id=>3041565, :neighbours=>["ES",
> "FR"], :flag=>"🇦🇩"}> (NoMethodError)
>
>           cols.each{|c| h[c.to_s] = get_column_value(c)}
>

This error is expected, since the json_serializer plugin calls methods to
get the values, in case the model is overriding the methods.  If there are
no methods defined for one of the columns, than an error is raised.

It's possible the json_serializer plugin could be modified to accept an
option to check if the method is defined before calling it (don't want to
do that by default as it is slower).


> It works (at least, I expect it works) by adding these two lines in the
> Country model :
>
> def_column_alias :code, :code
> def_column_alias :name, :name
>
> I'm not sure this is the right way to handle this case.
>

That should work around the error.


> I also expect to be able to move the select into Country model
> dataset_module :
>
> class Country < Sequel::Model(:country_info)
>   def_column_alias :code, :code
>   def_column_alias :name, :name
>
>   dataset_module do
>     select :api_subset,
>       Sequel[:iso_alpha2].as(:code),
>       Sequel[:country].as(:name),
>       :continent, :postal, :postal_regex,
>       :geoname_id,
>       Sequel.function(:string_to_array, :neighbours, ',').
>         as(:neighbours),
>       :flag
>    end
> end
>
> Is that the right way to deal with "legacy" databases ?
>

Maybe you don't need the json_serializer at all.  I doesn't look like you
are using the features it provides.  Try switching `.to_json` to
`.naked.to_a.to_json` and seeing if it works the way you want. If so, and
you aren't using the json_serializer plugin for another reason, you can
probably remove the use of json_serializer.

Thanks,
Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sequel-talk/CADGZSSewGKbX2LtyEqQghUk1T__5gZb6in841Wr3Kybr%2BMF_%3Dg%40mail.gmail.com.

Reply via email to