Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the DBIx-Class-Migration CPAN distribution.

Report information
The Basics
Id: 76322
Status: resolved
Priority: 0/
Queue: DBIx-Class-Migration

People
Owner: Nobody in particular
Requestors: frankschwach [...] yahoo.de
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.020
Fixed in: (no value)



Subject: Unexpected behaviour with TimeStamp component
DBIx-Class-Migration-0.020 on Ubuntu 10.10 Hi John, This may actually be an intentional feature but it is not mentioned in the documentation and it is not intuitive. When using migration scripts to load demo data into the database (as shown in the tutorial), it appears that the TimeStamp component is prevented from injecting a timestamp when a new record is created without explicitly defining a value for a date/time field that is not nullable and has the set_on_create attribute. This may be intentional to ensure the data is in a known state, which would not be the case if a current timestamp is inserted at creation time, but then it should be mentioned and ideally a warning should be issued otherwise it is difficult to find out what is going wrong. How to reproduce the error: Using the distribution of Test-DBIx-Class-0.31 in Test-DBIx-Class top level issue: $ mkdir /share $ dbic-migration --schema_class Test::DBIx::Class::Example::Schema -Ilib prepare $ touch share/migrations/SQLite/deploy/1/002-data.pl edit 002-data.pl to match the following: #!/usr/bin/env perl use strict; use warnings; use DBIx::Class::Migration::RunScript; migrate { my $self = shift; $self->schema->resultset('Company')->create({ company_id => '123', name => 'some_company', #-------------------------------------------------- # created => '01/04/2012', #-------------------------------------------------- } ); }; attempt to install the schema results in an error, desptie the fact that the created attribute of the Company Result class has the set_on_create attribute and should have passed: $ dbic-migration --schema_class Test::DBIx::Class::Example::Schema -Ilib install DBIx::Class::ResultSet::create(): DBI Exception: DBD::SQLite::st execute failed: company.company_id may not be NULL [for Statement "INSERT INTO company ( name) VALUES ( ? )"] at [..] uncomment the created line in the script above and installation succeeds. To verify that creation without passing a value to "created": $ touch insert_manually.pl edit the script to match: #!/usr/bin/env perl use strict; use warnings; use Test::DBIx::Class::Example::Schema; my $s = Test::DBIx::Class::Example::Schema->connect("dbi:SQLite:dbname=./share/test-dbix-class-example-schema.db","",""); $s->resultset('Company')->create( { company_id => '345', name => 'some_other_company', } ); run it: $ perl -Ilib insert_manually.pl passes without error and the data is in the DB: $ sqlite3 share/test-dbix-class-example-schema.db Show quoted text
sqlite> select * from company;
123|some_company|01/04/2012 345|some_other_company|2012-04-05 08:59:56 Cheers, Frank
From: frankschwach [...] yahoo.de
ooops, sorry, copied the wrong error message. What you get when running the install is of course this: DBIx::Class::ResultSet::create(): DBI Exception: DBD::SQLite::st execute failed: company.created may not be NULL [for Statement "INSERT INTO company ( company_id, name) VALUES ( ?, ? )"] On Thu Apr 05 05:47:19 2012, fschwach wrote: Show quoted text
> DBIx-Class-Migration-0.020 on Ubuntu 10.10 > > Hi John, > > This may actually be an intentional feature but it is not mentioned in > the documentation and it is not intuitive. When using migration > scripts > to load demo data into the database (as shown in the tutorial), it > appears that the TimeStamp component is prevented from injecting a > timestamp when a new record is created without explicitly defining a > value for a date/time field that is not nullable and has the > set_on_create attribute. > This may be intentional to ensure the data is in a known state, which > would not be the case if a current timestamp is inserted at creation > time, but then it should be mentioned and ideally a warning should be > issued otherwise it is difficult to find out what is going wrong. > > How to reproduce the error: > Using the distribution of Test-DBIx-Class-0.31 > in Test-DBIx-Class top level issue: > $ mkdir /share > $ dbic-migration --schema_class Test::DBIx::Class::Example::Schema > -Ilib > prepare > $ touch share/migrations/SQLite/deploy/1/002-data.pl > > edit 002-data.pl to match the following: > #!/usr/bin/env perl > > use strict; > use warnings; > use DBIx::Class::Migration::RunScript; > > migrate { > my $self = shift; > $self->schema->resultset('Company')->create({ > company_id => '123', > name => 'some_company', > #-------------------------------------------------- > # created => '01/04/2012', > #-------------------------------------------------- > } > ); > }; > > attempt to install the schema results in an error, desptie the fact > that > the created attribute of the Company Result class has the > set_on_create > attribute and should have passed: > > $ dbic-migration --schema_class Test::DBIx::Class::Example::Schema > -Ilib > install > DBIx::Class::ResultSet::create(): DBI Exception: DBD::SQLite::st > execute > failed: company.company_id may not be NULL [for Statement "INSERT INTO > company ( name) VALUES ( ? )"] at [..] > > uncomment the created line in the script above and installation > succeeds. > > To verify that creation without passing a value to "created": > > $ touch insert_manually.pl > > edit the script to match: > > #!/usr/bin/env perl > > use strict; > use warnings; > > use Test::DBIx::Class::Example::Schema; > > my $s = > Test::DBIx::Class::Example::Schema-
> >connect("dbi:SQLite:dbname=./share/test-dbix-class-example-
> schema.db","",""); > > $s->resultset('Company')->create( > { > company_id => '345', > name => 'some_other_company', > } > ); > > run it: > $ perl -Ilib insert_manually.pl > > passes without error and the data is in the DB: > $ sqlite3 share/test-dbix-class-example-schema.db
> sqlite> select * from company;
> 123|some_company|01/04/2012 > 345|some_other_company|2012-04-05 08:59:56 > > > Cheers, > > Frank
From: frankschwach [...] yahoo.de
and just to add: the same problem occurs with other components, for exapmle automatic hashing of passphrases with DBIx::Class::PassphraseColumn is also bypassed, so it is neccessary to manually create hashed passphrases from plain text and then to provide the hashed strings as input to passphrase fields. Otherwise, the plain text is entered as-is and user authentication against such records will fail. Of course one would have to do that anyway if using SQL to define the data to be loaded into the DB but it is unexpected when using the Perl Result classes themselves. Thanks for looking into this! Frank
From: frankschwach [...] yahoo.de
ok, the penny just dropped and I can now see why this is all happening - because, as you point out in the tutorial, the migratoin scripts work with a fresh schema, generated by the SchemaLoader, not with my Schema classes. Of course it makes perfect sense then that my additions to the Result classes are ignored. Let me change this from a bug report to a documentation request: could you maybe explicitly mention this potentially unintuitive consequence for working with DBIx components? Thanks! Frank
It's really an annoying little problem, isn't it? We HAVE to build a schema from the db, but they we get a schema that doesn't meet expectations. I will try to doc this harder, but I am starting to really think the only way to fix this is to serialize the actual schema you are using somehow. I will confer with Frew, the DBICDH author. I find this gets you in lots of little ways, like I am building a catalyst site that has a user table with a sha encoded password (using the DBIC:EncodedColumn comp) and I had to basically rewrite that comp just to instert seed data. Really, frustrating. If you have any thoughts other than seriailziing the actual db, I would love to hear them. right now I consider this the number 1 pain point. John On Thu Apr 05 14:05:09 2012, fschwach wrote: Show quoted text
> ok, the penny just dropped and I can now see why this is all happening - > because, as you point out in the tutorial, the migratoin scripts work > with a fresh schema, generated by the SchemaLoader, not with my Schema > classes. Of course it makes perfect sense then that my additions to the > Result classes are ignored. > Let me change this from a bug report to a documentation request: could > you maybe explicitly mention this potentially unintuitive consequence > for working with DBIx components? > Thanks! > Frank
Subject: Re: [rt.cpan.org #76322] Unexpected behaviour with TimeStamp component
Date: Thu, 5 Apr 2012 22:29:47 +0100 (BST)
To: "bug-DBIx-Class-Migration [...] rt.cpan.org" <bug-DBIx-Class-Migration [...] rt.cpan.org>
From: Frank Schwach <frankschwach [...] yahoo.de>
Hi John, yes, the password problem mirrors my experience and it IS a major gotcha at the moment. Not sure what the solution could be. I guess you need to be able to infer the Schema from the DB at every point during migration so you can run Perl scripts against the Schema at that point.  Ruby's ActiveRecord::Migration has a very similar caveat: if you want to use a model during migrations, the recommendation is to create a subsitute model class in the migration class itself and of course in AR the attributes of that class are always dynamically inferred from the rows of the corresponding table. I'm trying to think how something like that could be done in DBIC but I guess that would mean having to have a copy of all the Schema classes, right? Sorry if I can't be of much help here. Cheers, Frank Show quoted text
>________________________________ > Von: John Napiorkowski via RT <bug-DBIx-Class-Migration@rt.cpan.org> >An: frankschwach@yahoo.de >Gesendet: 20:56 Donnerstag, 5.April 2012 >Betreff: [rt.cpan.org #76322] Unexpected behaviour with TimeStamp component > ><URL: https://rt.cpan.org/Ticket/Display.html?id=76322 > > >It's really an annoying little problem, isn't it? > >We HAVE to build a schema from the db, but they we get a schema that doesn't meet >expectations.  I will try to doc this harder, but I am starting to really think the only way to fix >this is to serialize the actual schema you are using somehow.  I will confer with Frew, the >DBICDH author. > >I find this gets you in lots of little ways, like I am building a catalyst site that has a user table >with a sha encoded password (using the DBIC:EncodedColumn comp) and I had to basically >rewrite that comp just to instert seed data.  Really, frustrating. > >If you have any thoughts other than seriailziing the actual db, I would love to hear them.  right >now I consider this the number 1 pain point.  > >John > >On Thu Apr 05 14:05:09 2012, fschwach wrote:
>> ok, the penny just dropped and I can now see why this is all happening - >> because, as you point out in the tutorial, the migratoin scripts work >> with a fresh schema, generated by the SchemaLoader, not with my Schema >> classes. Of course it makes perfect sense then that my additions to the >> Result classes are ignored. >> Let me change this from a bug report to a documentation request: could >> you maybe explicitly mention this potentially unintuitive consequence >> for working with DBIx components? >> Thanks! >> Frank
> > > > >
On Thu Apr 05 17:29:57 2012, fschwach wrote: Show quoted text
> Hi John, > > yes, the password problem mirrors my experience and it IS a major > gotcha at the moment. Not sure what the solution could be. I guess > you need to be able to infer the Schema from the DB at every point > during migration so you can run Perl scripts against the Schema at > that point. 
Here's what I did to deal with the password thing. It's ugly but works: use Modern::Perl; use Digest; use DateTime; use DBIx::Class::Migration::RunScript; migrate { return unless $ENV{SEED_SHUTTERSTOCK_EXCHANGE}; my $encoder = sub { my $digester = Digest->new('SHA-256'); my ($plain_text) = @_; $digester->add($plain_text); return $digester->b64digest; }; my $person_rs = (my $self = shift) ->schema->resultset('Person'); my ($john, $logan) = map { $person_rs ->create($_) } ( { handle => 'John', email => 'johnn@shutterstock.com', password => $encoder->('abc123') }, { handle => 'Logan', email => 'lbell@shutterstock.com', password => $encoder->('abc123') }, ); my $why_chicken = $john->create_related(questions => { title => "Why did the chicken cross the road?", details => "I saw this chicken one day", asked_on => DateTime->now}); my $answer = $logan->create_related(answers => { content => "To get to the other side!", question_id => $why_chicken->id }); } Right now I have no ideal solution, unfortunately. The problem extends to a certain degree to DBIC::Fixtures as well. All this will need more pondering. I think at least it was good to get this far, and hopefully have something that does solve a lot of basic problems. Now just the problems are more edgy. John Show quoted text
> Ruby's ActiveRecord::Migration has a very similar > caveat: if you want to use a model during migrations, the > recommendation is to create a subsitute model class in the > migration class itself and of course in AR the attributes of that > class are always dynamically inferred from the rows of the > corresponding table. > I'm trying to think how something like that could be done in DBIC but > I guess that would mean having to have a copy of all the Schema > classes, right? > > Sorry if I can't be of much help here. > > Cheers, > > Frank > > > > > >
> >________________________________ > > Von: John Napiorkowski via RT <bug-DBIx-Class-Migration@rt.cpan.org> > >An: frankschwach@yahoo.de > >Gesendet: 20:56 Donnerstag, 5.April 2012 > >Betreff: [rt.cpan.org #76322] Unexpected behaviour with TimeStamp
> component
> > > ><URL: https://rt.cpan.org/Ticket/Display.html?id=76322 > > > > >It's really an annoying little problem, isn't it? > > > >We HAVE to build a schema from the db, but they we get a schema that
> doesn't meet
> >expectations.  I will try to doc this harder, but I am starting to
> really think the only way to fix
> >this is to serialize the actual schema you are using somehow.  I will
> confer with Frew, the
> >DBICDH author. > > > >I find this gets you in lots of little ways, like I am building a
> catalyst site that has a user table
> >with a sha encoded password (using the DBIC:EncodedColumn comp) and I
> had to basically
> >rewrite that comp just to instert seed data.  Really, frustrating. > > > >If you have any thoughts other than seriailziing the actual db, I
> would love to hear them.  right
> >now I consider this the number 1 pain point.  > > > >John > > > >On Thu Apr 05 14:05:09 2012, fschwach wrote:
> >> ok, the penny just dropped and I can now see why this is all
> happening -
> >> because, as you point out in the tutorial, the migratoin scripts
> work
> >> with a fresh schema, generated by the SchemaLoader, not with my
> Schema
> >> classes. Of course it makes perfect sense then that my additions to
> the
> >> Result classes are ignored. > >> Let me change this from a bug report to a documentation request:
> could
> >> you maybe explicitly mention this potentially unintuitive
> consequence
> >> for working with DBIx components? > >> Thanks! > >> Frank
> > > > > > > > > >
ALthough the general issue is still open, and I am working with frew to discuss approaches, I'm going to consider this a caveat to the way the system works for now and close this ticket. Thanks!