On Sunday, May 8, 2016 at 8:42:58 PM UTC-7, Janko Marohnić wrote:
>
> Hey Jeremy,
>
> The pg_json and pg_array extensions are awesome. However, I see people 
> often tripped about the load order, in the sense that they try to load the 
> extension after model definitions (that is, after the schema has already 
> been parsed), and then it silently doesn't work for them. I have two 
> improvements to this problem, which are not mutually exclusive (both can be 
> added).
>
> First one is that we add a warning when pg_json is loaded after schema has 
> already been parsed. As far as I know, schema is parsed only once, on first 
> model definition, am I correct? The documentation of pg_json extension 
> could also be updated to note that pg_json should be loaded before model 
> definitions.
>

Unfortunately, this mixes layers.  pg_json is a database extension, what 
you are taking about is model related.  Database code can never depend on 
model code, as you should always be able to use database code without 
models.

FWIW, the schema for the model is requested from the Database every time 
you set the model's dataset (generally once when the model class is 
initially created).  The Database caches schema entries, so future requests 
for the same table may not actually reparse the schema, unless you pass the 
appropriate option.
 

> Second one is, when loading the pg_json extension, if the schema is 
> already parsed, we could reiterate over it and change the :type to 
> :json/:jsonb if the :db_type is "json"/"jsonb". I'm aware that this is a 
> performance penalty, but the alternative is that typecasting simply doesn't 
> work. And people can always avoid the performance penalty by loading the 
> extension before schema parsing.
>

Likewise, this also mixes layers, and as such is not possible.
 

> Another reason why I would like the second one is that loading the 
> extension before schema parsing isn't always that easy. In my last job I 
> had a Sinatra application which lazily set the database connection 
> (accessible via App.database). And then the model was instantiated via 
> `class Post < Sequel::Model(App.database)`. This was done because we were 
> communicating with other databases as well. We couldn't put 
> `App.database.extension :pg_json` in the Sequel initializer, because at the 
> moment of requiring the initializer `App` wasn't defined yet. But the 
> `App.database` in model definitions worked because model files were 
> autoloaded, so the `App` was defined. After some investigating I somehow 
> found the solution: to use `Sequel::Database.extension :pg_json` in the 
> Sequel initializer, which was exactly what I wanted. However, it took me a 
> while to find out about it. If pg_json extension updated my parsed schema, 
> I'm pretty sure I would have no problem paying that small performance 
> penalty. And it kind of makes sense, to be able to do:
>
> class Post < Sequel::Model(App.database)
>   db.extension :pg_json
> end
>
> or
>
> App.database.extension :pg_json
>
> class Post < Sequel::Model(App.database)
> end
>
> However, now when I wrote all of this, I think I'm more in favour of just 
> adding the warning and changing documentation, because the above doesn't 
> actually feel right. I can make the PR for whatever we decide, just wanted 
> to ask you first what do you think about this.
>

If this is really an issue for you, you can set the model's dataset to the 
current dataset after loading the extension and reloading the schema:

class Post < Sequel::Model(App.database)
  db.extension :pg_json
  db.schema(table_name, :reload=>true)
  set_dataset(dataset)
end

But the recommended way would just be to get more control over the 
initialization process in your application so you can load extensions into 
your Database object right after it is created.

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 post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to