File: Spork.slides

package info (click to toggle)
libbio-chado-schema-perl 0.10010-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,800 kB
  • sloc: perl: 15,043; makefile: 7; sql: 3
file content (301 lines) | stat: -rw-r--r-- 7,414 bytes parent folder | download | duplicates (4)
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
----
presentation_topic: dbic_chado
presentation_title: Introduction to DBIx::Class
presentation_subtitle: 
presentation_place: Portland, OR
presentation_date: April 14, 2010
----
= What is DBIx::Class?

* Object-relational mapping framework for Perl
* is now the de-facto standard
* nice features

----
= What is DBIx::Class?

* query building (the magic of chainable ResultSets)
* cross-database deployment (using |SQL::Translator| in the backend)
* lots and lots of plugins availabe (dates, testing, ...)

see the manual: http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Manual.pod

----
= What it looks like

  package My::Schema;

  __PACKAGE__->load_namespaces;

  package My::Schema::Result::Foo;

  __PACKAGE__->table('foo');
  __PACKAGE__->add_columns(qw( foo_id bar baz ));
  __PACKAGE__->has_many('bars' => 'My::Schema::Result::Bar');
  # also belongs_to  many_to_many

  package My::Schema::Result::Bar;

  __PACKAGE__->table('bar');
  # and so on

* use |DBIx::Class::Schema::Loader| to generate this from a DB
* use |$schema->deploy| to make a DB from this

----
= Basic Usage

* open the schema.  ( actual DB connection is deferred )
+  my $schema = My::Schema->connect( 'dbi:Pg:...', $user, $pass );

+* get a ResultSet object representing a set of Rows
+  my $orgs_rs = $schema->resultset('Organism');

+* take a subset of those (another ResultSet)
+  my $chickeny_things = $orgs_rs->search({ genus => 'Gallus' });

+* first one in the result set
+  my $chicken = $chickeny_things->first;     #< actual query is run

----
= Basic Usage

+* getting actual data
+  my $wombat = $orgs_rs->find( 232432 );
+  say $wombat->genus.' '.$wombat->species; #< print 'Vombatus ursinus' or something

  # or search in list context returns all resulting rows
  my @all_nightshades = $orgs_rs->search({ genus => 'Solanum' });

----
= Basic Usage

* traverse relationships (joined queries)
+  my $chickeny_things = $ck_rs->search({ genus => 'Gallus' });
+  my @chr = $chickeny_things->chromosomes;  #< query is run here
+  my @genes = $chicken->chromosomes->features->search({ type => 'gene' });

+* loading
+   $orgs_rs>create({ genus => 'Mus', species => 'musculus' })
+   # or piecewise
+   my $new = $orgs_rs->new;
   $new->genus('Mus');  $new->species('musculus');
   $new->insert;

+* deleting
  $chicken->chromosomes->features->search({ type => 'gene' })->delete;


----
= When not to use DBIC

* tiny app, tiny schema (setup overhead)
+* or tiny number of different queries
+* or hate objects

strengths/weaknesses ...

----
= Strengths and Weaknesses

* strengths
+** chainable ResultSets
+** lazy querying
+** good support for custom SQL
+** prefetching
+** lots of nice extensions

+* weaknesses
+** non-ORM-y things are possible, but can be cumbersome

----
= Chainable ResultSets

  my $styx_tracks =
       $music_schema->resultset('Artist')
                    ->search({ name => 'Styx' })
                    ->albums
                    ->tracks;

  SELECT ...
    FROM artist
    JOIN albums ON ...
    JOIN tracks ON ...
    WHERE artist.name = 'Styx'

----
= Lazy Querying

* does not run the query until data is actually needed

  # fetch all
  my @tracks = $styx_tracks->all;

  # or iterate
  while( my $track = $styx_tracks->next ) { ... }

----
= Custom SQL

* can make a view |ResultSource| for big tuned queries

  package My::Schema::SummarizedFrobs;
  __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
  __PACKAGE__->result_source_instance->view_definition(<<'');
     SELECT omg_so_much_stuff
     UNION
     SELECT ( SELECT blah blah blah FROM blah ),
            ( blah blah blah ),
     WHERE blah blah blah
     UNION
        blah blah blah
      
  __PACKAGE__->add_column( <cols in your view> )

----
= Custom SQL

* for custom conditions, searches accept |SQL::Abstract| syntax

  $schema->resultSet('Sequence::Feature')
         ->search({
              'me.feature_id' =>
                \[ "IN( select feature_id from clone_feature where clone_id = ?)",
                   [ dummy => $self->clone_id ],
                 ],
              },
              { rows => 10,
                order_by => [qw[ me.name me.type_id ]],
                having
              });


----
= Prefetching

  # query will get the wombat organism, and also prefetch *all its
  # chromosomes and features on those chromosomes*
  my $rs = $schema->resultset('Organism')->search(
   { genus => 'Vombatus', species => 'ursinus' },
   { prefetch => { chromosomes => features => } },
  );

(in a real biological DB this would probably blow your memory)

----
= Extensions

* |DBIx::Class::Helpers|
** |fREW|'s miscellaneous things
+* |DBIx::Class::Cursor::Cached|
** tunable, flexible resultset caching
+* |DBIx::Class::Ordered|
** nice for doing ordering or ranking columns in a table
+* |DBIx::Class::InflateColumn::DateTime|, |DBIx::Class::Timestamp|
** work with dates, times, and timestamps as |DateTime| objects

----
= Thread-Safe / Fork-Safe

* |theory|'s |DBix::Connector|

----
= Non-linear Join

  # get features via the potato organism, also joining in the cvterms table
  my $potato_bacs =
       $schema->resultset('Organism')
              ->search({ species => 'Solanum tuberosum' })
              ->search_related( 'features',
                               { 'type.name' => 'BAC_clone'},
                               { 'join' => 'type' },
                             );

----
= Non-linear Join

  # the equivalent bare SQL
  my $potato_bacs = $dbh->selectall_arrayref( <<EOS, undef, 'Solanum tuberosum', 'BAC_clone');
  SELECT features.feature_id
       , features.dbxref_id
       , features.organism_id
       , features.name
       , features.uniquename
       , features.residues
       , features.seqlen
       , features.md5checksum
       , features.type_id
       , features.is_analysis
       , features.is_obsolete
       , features.timeaccessioned
       , features.timelastmodified
  FROM organism me
  LEFT JOIN feature features
         ON features.organism_id = me.organism_id
  JOIN cvterm type
         ON type.cvterm_id = features.type_id
  WHERE species = ? AND type.name = ?
  EOS

----
= Convenient Loading of Relationships

  $chado->resultset( 'Cv::Cv' )
        ->find_or_create({ name => 'My Fake Ontology' })
        ->create_related(  'cvterm',
                           { name => 'MyFakeTerm' });

makes the SQL:

  SELECT me.cv_id
       , me.name
       , me.definition
  FROM cv me
  WHERE ( me.name = 'my fake ontology' )

  INSERT INTO cv ( name )
          VALUES ( 'my fake ontology' )
       RETURNING cv_id

  INSERT INTO cvterm ( cv_id,  name        )
              VALUES ( ?,     'MyFakeTerm' )

----
= Transactions

  $schema->txn_do(sub {

      $schema->resultset('Cv::Cv')
             ->find_or_create({ name => 'My Fake Ontology' })
             ->create_related( 'cvterm', { name => 'MyFakeTerm' } );

  });

----
= The Real Advantages of DBIC

* easier to manipulate and assemble queries

----
= The Real Advantages of DBIC

* complex joined queries (Chado queries) are very easy and compact

----
= The Real Advantages of DBIC

* SQL syntax errors are more difficult to make

----
= The Real Advantages of DBIC

* it's all objects.  you can delegate to them, pass them around, etc.
* HOWEVER:
+** usually you don't want to subclass them
** but, see |DBIx::Class::Manual::Cookbook|

----
== That's All

* The END