On May 9, 5:38 pm, Stefan <[email protected]> wrote: > On May 8, 6:42 pm, Jeremy Evans <[email protected]> wrote: > > > On May 8, 4:07 am, Stefan <[email protected]> wrote: > > > > Hello, > > > > I have two questions. > > > > First question: How can I subclass Sequel::Model without having DB > > > connection? > > > You don't. Well, you can hack the internals and do so, but I won't > > support that. > > Why?
Subclass creation is when Sequel queries the database to get the column information for the model. If the database connection isn't available, you won't be able to get the columns, and the column accessors won't be created. It is possible to work around the issues later by changing the model's dataset, if you have at least a dummy database set up first. Long story short, the modifications to have it not raise an error are not extensive, but I think raising an error is a better default, since otherwise we would have users that complained that they don't have column accessors for their models (which did happen before Sequel raised an error in this case). > > > When I do: > > > > class ETLJobSchedule < Sequel::Model > > > ... > > > end > > > > I get: > > > > /Library/Ruby/Gems/1.8/gems/sequel-3.11.0/lib/sequel/model/base.rb: > > > 125:in `db': No database associated with Sequel::Model (Sequel::Error) > > > from /Library/Ruby/Gems/1.8/gems/sequel-3.11.0/lib/sequel/model/ > > > base.rb:191:in `inherited' > > > That's by design. > > What is the reason for that? See above. > > > I do not know DB connection at the time of Class *declaration* and I > > > would like to set it up later, for example like this: > > > > ETLJobSchedule.set_dataset(@connecti...@etl_schedules_table]) > > > The model class isn't usable until the database connection has been > > established. Connect to the database first, then load your model > > classes. > > > > Second question: How can I have model instances from different > > > connections? > > > You can have model classes with separate database connections: > > > class ModelA < Sequel::Model(DB1[:table1]) > > end > > > class ModelB < Sequel::Model(DB2[:table2]) > > end > > This is what I wanted to avoid. Then you'll want to go with sharding. > > The Sequel::Model method takes any dataset, so it's easy to specify > > that the model class should use a specific database by giving it a > > dataset from that database. > > > If you meant how to get two model instances from the same class to > > connect to different Database objects, you can't. > > > > Example situation: I have more DBs or DB schemas with a table with > > > same structure. How can I use Sequel::Model with more connections > > > where the same structure exist? > > > For that, look into Sequel's sharding > > functionality:http://sequel.rubyforge.org/rdoc/files/doc/sharding_rdoc.html > > In this case it is not about sharding. I simply have multiple separate > databases with same structure but different data and I want to manage > them from single point/application. "Separate databases per customer" versus "sharding by customer" is a semantic argument I don't want to get into. I'll just state that Sequel's sharding functionality is useable in any case where you have multiple databases with the same schema. It works for master/slave databases, separate databases per customer, and traditional partitioning. > > However, sharding is more of a dataset feature, and while models have > > full support for sharding when retrieving records, there isn't any > > built in support for saving records to specific shards. It's probably > > not hard to add if you need it, though. > > > > Two entry points for specifying connection are sufficient for me: one > > > factory method (that creates model instances) and method for selecting > > > objects (find). > > > > Something like: > > > schedule = ETLJobSchedule.new_from_connection(@connection) > > > schedules = ETLJobSchedule.find_using_connection(@connection, ...) > > > That's not how Sequel works. You don't deal with connection objects, > > and while Sequel does make them available if you need them for low > > level stuff, there's no Sequel methods that accept them as arguments. > > You can do something like: > > > schedules = ETLJobSchedule.server(:shard_id).first(...) > > > To retrieve schedules from a specific shard. > > > However, the new_from_connection can't be duplicated without some > > small extensions. Currently you'd need to override Model#_insert > > (kind of large), but I'd be OK with refactoring so that you'd only > > need to override a new method like _insert_dataset. For updating and > > deleting records, you would have to override _update_dataset and > > _delete_dataset. The only issue there is that Sequel does not store > > which shard was used to retrieve the objects. For that you could use > > the tactical_eager_loading plugin, and call retrieved_by to get access > > to the dataset that was used to retrieve the object, and get the shard > > id to use in _update_dataset and _delete_dataset. > > See above: no sharding - just more different DBs. It works for both cases. > > > Something analogous to Core Data where you can have more object stores > > > for one object model. > > > I'm not familiar with Core Data. > > It might be interesting to look at it, at least the architecture and > approach to certain functionalities. > > > Anyway, hope this helps. If you have more questions, just respond. > > Yes, it helped. Thanks. Hopefully you also got my later message, which included the following text: Try the patch at http://pastie.org/951880.txt combined with the plugin at http://pastie.org/951879.txt. It's very similar in terms of API as they examples you gave. Jeremy -- You received this message because you are subscribed to the Google Groups "sequel-talk" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sequel-talk?hl=en.
