Hi Tim,

I'm entering this conversation late and haven't used the migration feature
of Cayenne before (outside of CreateIfNoSchemaStrategy for testing), but we
*do* use automated migrations here with our Tapestry project using
http://flywaydb.org/ (inside and outside of Cayenne/Tapestry).

With Flyway, you create SQL scripts and/or Java-based migrations.  You can
run migrations/etc from Maven, the application, command-line, etc.

For our project, we decided to always migrate outside of the application
using Maven (more flexible that way, plus our application doesn't run with
DB administrator privileges so it cannot create tables/etc), but have the
application validate upon startup (and a symbol to be able to disable it on
startup in an emergency):

    @Startup
    public void verifyDatabaseMigrations(@Symbol(FLYWAY_ENABLED) boolean
flywayEnabled)
    {
        if (flywayEnabled)
        {
            DataContext context    = DataContext.createDataContext();
            DataSource  dataSource =
context.getParentDataDomain().getNode("analytic").getDataSource();
            Flyway      flyway     = new Flyway();

            flyway.setDataSource(dataSource);
            flyway.validate();
        }
    }

If the validate() call fails (the DB isn't current) an exception is thrown
and the application fails to start.  If you actually wanted the application
to migrate, you could change validate() to migrate() and it would migrate
all new SQL/Java migrations for you or throw an exception on failure.

Not sure if this helps you or not, but thought I'd toss an alternative
approach out for your consideration.  If this interests you, I can answer
more questions about it.

mrg



On Mon, Mar 24, 2014 at 11:21 PM, D Tim Cummings <[email protected]>wrote:

> Thanks. I didn't think of that.
>
> So now I am putting the migrations into my app.
>
> 1. I have worked out I need to change the Cayenne Model schema update
> strategy in cayenne-project.xml from
>
>
> schema-update-strategy="org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy"
>
> to
>
>
> schema-update-strategy="org.apache.cayenne.access.dbsync.SkipSchemaUpdateStrategy"
>
> 2. I added the generated Datamap0.java into my project.
>
> 3. I added a method in my AppModule of my Tapestry project to run at
> startup to migrate to latest. Is this the correct way of getting domain?
>
>   @Startup
>   public static void initMigrateToLatest() {
>     try {
>       ServerRuntime sr = new ServerRuntime("cayenne-project.xml");
>       DataDomain domain = sr.getDataDomain();
>       new Migrator(domain.getDataNode("datanode"),
> Datamap0.class.getPackage().getName()).migrateToLatest();
>     } catch (SQLException e) {
>       throw new RuntimeException("Unable to migrate database to current
> version: " + e.getMessage(), e);
>     }
>   }
>
> 4. Now I am having a problem with auto_increment fields. For example I
> have a table called tbl_company. If it is created using Cayenne's
> CreateIfNoSchemaStrategy then it looks like this
>
> mysql> describe tbl_company;
> +-------------+--------------+------+-----+---------+----------------+
> | Field       | Type         | Null | Key | Default | Extra          |
> +-------------+--------------+------+-----+---------+----------------+
> | date_cancel | datetime     | YES  |     | NULL    |                |
> | date_create | datetime     | YES  |     | NULL    |                |
> | id_company  | int(11)      | NO   | PRI | NULL    | auto_increment |
> | str_company | varchar(255) | YES  |     | NULL    |                |
> +-------------+--------------+------+-----+---------+----------------+
>
>
> If I create it using cayenne-migrations and Datamap0 it looks like this.
> (Note no auto_increment on id).
>
> mysql> describe tbl_company;
> +-------------+--------------+------+-----+---------+-------+
> | Field       | Type         | Null | Key | Default | Extra |
> +-------------+--------------+------+-----+---------+-------+
> | date_cancel | datetime     | YES  |     | NULL    |       |
> | date_create | datetime     | YES  |     | NULL    |       |
> | id_company  | int(11)      | NO   | PRI | NULL    |       |
> | str_company | varchar(255) | YES  |     | NULL    |       |
> +-------------+--------------+------+-----+---------+-------+
>
>
> My Datamap0 for this table is
>
> MigrationTableNew tbl_company = db.createTable("tbl_company");
>  tbl_company.addTimestampColumn("date_cancel", 19);
> tbl_company.addTimestampColumn("date_create", 19);
>  tbl_company.addIntegerColumn("id_company", MANDATORY, null);
> tbl_company.addVarcharColumn("str_company", 255);
>  tbl_company.addPrimaryKey("id_company");
>
>
> My datamap.map.xml for this table is (Note the isGenerated="true")
>
> <db-entity name="tbl_company">
> <db-attribute name="date_cancel" type="TIMESTAMP" length="19"/>
>  <db-attribute name="date_create" type="TIMESTAMP" length="19"/>
>
> <db-attribute name="id_company" type="INTEGER" isPrimaryKey="true" 
> isGenerated="true" isMandatory="true" length="10"/>
>  <db-attribute name="str_company" type="VARCHAR" length="255"/>
>  </db-entity>
>
> So my question is, how do I get cayenne-migrations to create the
> auto_increment in MySQL.
>
> Thanks
>
> Tim
>
> On 25 Mar 2014, at 0:11, John Huss <[email protected]> wrote:
>
> I usually run MigrationGenerator from eclipse.  You can just create a new
> "Java Application" launch configuration for the project and enter
> "org.apache.cayenne.migration.MigrationGenerator" as the main class.  And
> then on the arguments tab enter your cayenne project filename and the
> output directory.  For example "cayenne-MyDomain.xml ."  (dot for the
> current directory).
>
>
>

Reply via email to