SlideShare uma empresa Scribd logo
1 de 48
Baixar para ler offline
Wednesday, March 21, 12
Coding & Development




                          Getting It Into Drupal With
                                    Migrate


                          Presented by drewish (Andrew Morton)
                              drewish@katherinehouse.com


Wednesday, March 21, 12
So You’ve Got This
                            Old Website...


Wednesday, March 21, 12

Let’s do some shows of hands on what people are doing right now. Feeds? Custom scripts?
Intern data entry? How many just know you’re going to have to in the next 6-months.
My Goals
                   •      Give you mental framework to
                          understand Migrate.
                   •      Step through the basics of building a
                          migration.
                   •      Convince to use Migrate rather than
                          custom one-off scripts and/or add Migrate
                          support to your modules.


Wednesday, March 21, 12

Put another tool in your toolbox... and just talk you into using feeds.
Migrate has lots of pieces that are badly named making it harder to understand.
Migrate 2.0
                   •      Powerful object oriented framework for
                          moving content into Drupal.
                   •      Minimal UI, primarily code based.
                   •      Steep learning curve.




Wednesday, March 21, 12

I’ve been using Migrate for almost a year and was annoying enough in the issue queue that
the just made me a maintainer.
<See if Mike and Moshe are in the crowd and introduce them>
Explain the differences between v2 and v1.
aka migraine module, but hopefully this talk will help.
Wednesday, March 21, 12

There’s a basic UI and great drush support. I’m going to ignore them because of time
constraints.
Migrate 2.0
                   •      Drupal 6 requires autoload and dbtng
                          modules. So the code is very similar in 6
                          and 7.
                   •      Migrate Extras provides support for many
                          contrib modules.
                   •      The most comprehensive and up-to-date
                          documentation is the beer.inc and wine.inc
                          examples.


Wednesday, March 21, 12

Well these slides are really the best... but the might get out of date.
Why not just use
                               Feeds?
                   •      If it does what you need, use it. It’s much
                          easier to setup.
                   •      Migrate is performant, and more flexible
                          but requires that you write code to map
                          fields.
                   •      Feeds doesn’t work well if you’ve got
                          different content types that need to
                          reference each other.


Wednesday, March 21, 12

Get asked this a lot. I’m pragmatic, use the best tool.
Theory



Wednesday, March 21, 12
Source & Destination

                          Source     Destination
                           Field 1      Field 1
                           Field 2      Field 2
                           Field 3      Field 3
                          Field ID        ID




Wednesday, March 21, 12
Source
                   •      Interface to your existing data (SQL, CSV,
                          XML, JSON).
                   •      Provides a list of fields and descriptions.
                   •      Responsible for iterating over rows.




Wednesday, March 21, 12
Destination
                   •      Responsible for writing a specific type of
                          data to Drupal, e.g. Node, User, or other
                          Entity, but could be something like a SQL
                          row.
                   •      Creates one Destination record for each
                          Source record.




Wednesday, March 21, 12

Knows how to save it... user_save(), node_save(), entity_save(), db_insert(), etc.
So, if you’re creating users and profiles, you’ll need to do it in two migrations.
Map the Fields

                          Source                     Destination
                           Field 1   Field Mapping      Field 1
                           Field 2                      Field 2
                           Field 3                      Field 3
                          Field ID   Field Mapping        ID




Wednesday, March 21, 12

With these pieces you’ve basically got feeds.
Field Mappings
                          Source                       Destination
                 ID       Name    Age      Other      entity_id   field_age   field_name

                 1        Larry   34       blah          32          34        Larry
                 2        Curly   54                     33          54        Curly
                 4         Moe    47        junk         34          47         Moe



                                  Field Mappings
                                        Source     Destination
                                         Name      field_name
                                         Age        field_age
                                        Other         NULL

Wednesday, March 21, 12
Field Mappings
                   •      Links a source field to a destination field.
                   •      Has some basic functions to transform
                          values splitting on separators, etc.
                   •      Holds additional arguments to pass on to
                          the destination field.




Wednesday, March 21, 12

Might skip over the source id lookup since we haven’t really talked about migration maps yet.
Migration Map

                          Source                              Destination
                           Field 1   Field Mapping                  Field 1
                           Field 2                                  Field 2
                           Field 3                                  Field 3
                          Field ID   Field Mapping                    ID




                                          Map

Wednesday, March 21, 12

Now we need to do a little more than what Feeds provides. Lets track IDs so when we import
users and articles we can attribute the articles to the correct user.
Map
                   •      Connects the Source and Destination IDs
                          allowing translation between them.
                   •      Tracks the keys’ schema format.
                   •      Allows a migration to re-run and update
                          existing records.
                   •      Allows imported records to be deleted
                          during a rollback.


Wednesday, March 21, 12

Also provides some other benefits.
Composite keys are supported.
Migration
                                        Migration
                          Source                                Destination
                           Field 1    Field Mapping                   Field 1
                           Field 2                                    Field 2
                           Field 3                                    Field 3
                          Field ID    Field Mapping                     ID




                                         Map
                  prepareRow(), prepare(), complete()

Wednesday, March 21, 12

I’m going to ignore those three little functions for now but I just wanted to put them on here
so you can visualize where they live.
Migration
                   •      Sets up all the necessary pieces: Source,
                          Destination, Map and Field Mappings.
                   •      May provide logic for skipping over rows
                          during the migration.
                   •      May alter the entities during the
                          migration.



Wednesday, March 21, 12

Your class that glues all the parts together.
Field Handlers
                                        Migration
                          Source                                Destination
                           Field 1   Field Mapping                    Field 1
                           Field 2
                           Field 3                                Field Handler
                          Field ID   Field Mapping                    Field 2
                                                                  Field Handler
                                                                      Field 3
                                                                  Field Handler
                                                                        ID
                                         Map
                  prepareRow(), prepare(), complete()

Wednesday, March 21, 12

If you think about the way the data would be coming out of the Source it’ll be “flat” values
like strings or integers. Drupal fields are typically nested arrays and something needs to
know the format of those arrays, hence the field handler.
Field Handlers
                   •      Handles the details of converting the
                          Source value into the structure that
                          Drupal understands.
                   •      Turns $row->bar   = “foo”   into
                          $entity->field_bar[‘und’][0][‘value’] = “foo”

                   •      Might pull additional data out of
                          arguments.



Wednesday, March 21, 12
Destination Handler
                                       Migration
                          Source                        Destination
                           Field 1   Field Mapping         Field 1
                           Field 2
                           Field 3                      Field Handler
                          Field ID   Field Mapping         Field 2
                                                        Field Handler
                                                           Field 3
                                                        Field Handler
                                                             ID
                                         Map            Destination
                  prepareRow(), prepare(), complete()   Handler(s)

Wednesday, March 21, 12
Destination Handler
                   •      “Magically” extends an existing
                          destination and adds functionality, e.g.
                          MigrateCommentNodeHandler adds a comment
                          status field to nodes.
                   •      Contrib maintainers might need to create
                          these.




Wednesday, March 21, 12
Practice



Wednesday, March 21, 12
Basic Migrate Module
                   •      Create a new module to so you can disable it
                          once the site launches.

                   •      Implement hook_migrate_api() in the .module file.
                   •      Create a class that extends Migration and in
                          the constructor setup the Source, Destination,
                          Map and Field Mappings.

                   •      Register the class’s file in the .info file.



Wednesday, March 21, 12

If I’m being lazy and it’s only a single migration class I’ll just throw it in the .module file.
Migration Class
                   •      Setup the Source, Destination, Map and
                          Field Mappings in the constructor:
                   class BasicExample extends Migration {
                     public function __construct() {
                       parent::__construct();
                       $this->source = ???;
                       $this->destination = ???;
                       $this->map = ???;
                       $this->addFieldMapping(???, ???);
                     }
                   }




Wednesday, March 21, 12

You’ll probably have more than one Field Mapping.
SQL Source
                   // inside __construct()

                   $query = db_select('migrate_example_beer_topic',
                   'met')
                     ->fields('met', array('style', 'details',
                       'style_parent', 'region', 'hoppiness'))
                     ->orderBy('style_parent', 'ASC');

                   $this->source = new MigrateSourceSQL($query);




Wednesday, March 21, 12

Able to extract the field names from the query. Descriptions are optional.
Or a CSV Source
                   // The definition of the columns. Keys are integers,
                   // values are an array of field name then description.
                   $columns = array(
                     0 => array('cvs_uid', 'Id'),
                     1 => array('email', 'Email'),
                     2 => array('name', 'Name'),
                     3 => array('date', 'Date'),
                   );

                   // Instantiate the class using the path to the CSV
                   // file and the columns.
                   $path = 'path/relative/to/drupal/root/your_file.csv';
                   $this->source = new MigrateSourceCSV($path, $columns);




Wednesday, March 21, 12

The CSV source can actually use the header row as column names but I’m not going to
demonstrate that.
Other Sources
                   •      There are also classes for importing
                          content from XML and JSON.
                   •      Lots of variation among sources so expect
                          to do some tweaking.




Wednesday, March 21, 12
Source Base Classes
                   •      If you can fetch IDs separately from values:
                          •   Use MigrateSourceList as a source
                          •   Implement MigrateList for fetching counts and IDs,
                              and MigrateItem for fetching values
                   •      If everything is in a single file with IDs mixed in:
                          •   Use MigrateSourceMultiItems as a source
                          •   Implement MigrateItems for extracting IDs and
                              values


Wednesday, March 21, 12

I don’t really want to get too deep into this. I’m mentioning them so you’ll know they’re here
when you discover you need them.
Migration Map
                   // inside __construct()

                   $this->map = new MigrateSQLMap($this->machineName,
                      // You’ve got to describe your id’s schema.
                      array(
                         'style' => array(
                           'type' => 'varchar',
                           'length' => 255,
                           'not null' => TRUE,
                         )
                      ),
                      // Most Destinations provide a helper function:
                      MigrateDestinationTerm::getKeySchema()
                   );




Wednesday, March 21, 12
Destinations
                   // inside __construct()

                   // Create terms...
                   $this->destination = new
                     MigrateDestinationTerm('example_beer_styles');

                   // ...or nodes...
                   $this->destination = new
                     MigrateDestinationNode('article');

                   // ...or
                   $this->destination = new
                     MigrateDestinationUser();




Wednesday, March 21, 12
Field Mappings
                   // inside __construct()

                   // Can be as simple as this…
                   $this->addFieldMapping('dest_name', 'source_name');

                   // …or you can chain options onto it…
                   $this->addFieldMapping('dest_name')
                     ->defaultValue(1);

                   // Lets pretend we already setup $arguments.
                   $this->addFieldMapping('field_favbeers', 'beers')
                     ->separator('|')
                     ->arguments($arguments);




Wednesday, March 21, 12
Field Mapping
                                 Arguments
                   •      Often used to pass multiple source fields
                          into a single destination field.
                   •      First argument will be the teaser field, the
                          second argument will always be one:
                          $this->addFieldMapping('body', 'body')
                            ->arguments(array(
                             'summary' => array('source_field' => 'teaser'),
                             'format' => 1
                            ));




Wednesday, March 21, 12

By default the values passed into the arguments will be used as literals. If you use that wacky
array syntax it’ll replace it with the value from that field on the current row.
Field Mapping
                             Arguments
                   $path = drupal_get_path('module', 'migrate_example');
                   // You could use the helper...
                   $arguments = MigrateFileFieldHandler::arguments(
                     $path, 'file_copy', FILE_EXISTS_RENAME, NULL,
                     array('source_field' => 'image_alt'));
                   $this->addFieldMapping('field_image', 'image')
                     ->arguments($arguments);

                   // Or skip it and end up with more readable code:
                   $this->addFieldMapping('field_image', 'image')
                     ->arguments(array(
                       'source_path' => $path,
                       'alt' => array('source_field' => 'image_alt'),
                     ));




Wednesday, March 21, 12

So two versions that do the same thing. I’m showing you this to demonstrate that some of
the helpers actually obscure the functionality with out adding much value.
Field Mapping
                          Source Migrations
                   •      When you have an ID value from the old
                          system and need to look up the new ID
                          from the Migration Map:
                          $this->addFieldMapping('uid', 'author_id')
                            ->sourceMigration('BeerUser')

                   •      Add a dependency to make sure the
                          other migration runs first:
                          $this->dependencies = array('BeerUser');




Wednesday, March 21, 12
But Wait, There’s
                                 More!
                   •      You can implement methods to customize
                          the process: prepareRow(), prepare(), complete().
                   •      Yeah, it might be hard to remember which
                          prepare does what.




Wednesday, March 21, 12
prepareRow($row)
                   •      Passes in the source row as an object so
                          you can make modifications.
                   •      Can indicate that a row should be skipped
                          over during the import by returning FALSE.
                   •      Add or change field values by modifying
                          the properties:
                          $row->first = drupal_strtoupper($row->first);
                          $row->created = strtotime($row->access);




Wednesday, March 21, 12

Need to mention that if you add a field in prepareRow() you should really add it to the
Source’s field list.
prepare($entity, $row)
                   •      Passes in the entity object with properties
                          populated by field mappings, and the
                          source row.
                   •      Last chance to make changes before the
                          entity is saved.
                   •      If you have an unsupported field type you
                          can manually populate it here:
                          $entity->field_foo[‘und’][0][‘foo’] = $row->foo;




Wednesday, March 21, 12
complete($ent, $row)
                   •      Passes in the saved entity (with any ID
                          values from auto increment fields) and the
                          source row.
                   •      This is the place if you need to update other
                          records to reference the new entity.
                   •      If you’re calling node_save() or entity_save() on
                          the record you just imported, you’re
                          probably doing something wrong.


Wednesday, March 21, 12
Dealing With Circular
                    Dependencies
                   •      Break them by using stubs.
                   •      Specify a sourceMigration(‘BeerUser’) on the ID’s
                          field mapping.
                   •      Add createStub($migration, $source_key) to BeerUser
                          which creates an empty record and returns the
                          new id.
                   •      When BeerUser runs it’ll update the stub and fill
                          it with the real values.


Wednesday, March 21, 12

Basically one migration asks another to look up the ID mapping, if it doesn’t exists the
second migration will create an empty record to get an ID so the first migration can complete.
Then when the second migration runs it will update the dummy record that was created
earlier.
Import Flow
                                         Migration
                          Source                        Destination
                           Field 1     Field Mapping       Field 1
                           Field 2
                           Field 3                      Field Handler
                          Field ID     Field Mapping       Field 2
                                                        Field Handler
                                                           Field 3
                                                        Field Handler
                                                             ID
                                         Map             Destination
                  prepareRow(), prepare(), complete()    Handler(s)

Wednesday, March 21, 12
Import Flow
                   •      Source iterates until it locates an appropriate record, then
                          calls the Migration’s prepareRow($row) letting you modify or
                          reject the data in $row.
                   •      Migration applies the Field Mappings and the Field
                          Handlers to convert the data in $row into $entity.
                   •      Migration calls prepare($entity, $row) letting you modify the
                          final entity using data from the Source’s row.
                   •      Destination saves the entity.
                   •      Migration records the IDs into the Map then calls complete()
                          so you can see the entity’s final ID.



Wednesday, March 21, 12
Supporting Migrate in
                       Contrib
                   •      If you’re creating new objects (e.g.
                          Webform Submissions) write a
                          Destination.
                   •      If you’re writing field modules write a
                          Field Handler.




Wednesday, March 21, 12
Creating Destinations
                   •      Hopefully you won’t need to…
                   •      If you’re working with entities created by
                          the Entity API make sure you look at:
                          http://drupal.org/node/1168196




Wednesday, March 21, 12
Creating Field
                                Handlers
                   •      Look at extending MigrateSimpleFieldHandler
                          for single value fields.
                   •      In the constructor register your field types.
                   •      In prepare() convert the value into the
                          format your field requires.
                   •      Optionally, in complete() handle any
                          followup tasks that require the entity’s ID.


Wednesday, March 21, 12
Questions?
                                         Migration
                          Source                        Destination
                           Field 1     Field Mapping       Field 1
                           Field 2
                           Field 3                      Field Handler
                          Field ID     Field Mapping       Field 2
                                                        Field Handler
                                                           Field 3
                                                        Field Handler
                                                             ID
                                         Map             Destination
                  prepareRow(), prepare(), complete()    Handler(s)

Wednesday, March 21, 12
What did you think?
                           Locate this session on the
                           DrupalCon Denver website
                          http://denver2012.drupal.org/program

                           Click the “Take the Survey” link.


                                 Thank You!
Wednesday, March 21, 12

Mais conteúdo relacionado

Semelhante a Migrate

Distributed data mining
Distributed data miningDistributed data mining
Distributed data miningAhmad Ammari
 
Linking data without common identifiers
Linking data without common identifiersLinking data without common identifiers
Linking data without common identifiersLars Marius Garshol
 
Pinterest的数据库分片架构
Pinterest的数据库分片架构Pinterest的数据库分片架构
Pinterest的数据库分片架构Tommy Chiu
 
Intro to Big Data and NoSQL
Intro to Big Data and NoSQLIntro to Big Data and NoSQL
Intro to Big Data and NoSQLDon Demcsak
 
Ml pluss ejan2013
Ml pluss ejan2013Ml pluss ejan2013
Ml pluss ejan2013CS, NcState
 
Introduction to Apache Accumulo
Introduction to Apache AccumuloIntroduction to Apache Accumulo
Introduction to Apache AccumuloJared Winick
 
Django and Neo4j - Domain modeling that kicks ass
Django and Neo4j - Domain modeling that kicks assDjango and Neo4j - Domain modeling that kicks ass
Django and Neo4j - Domain modeling that kicks assTobias Lindaaker
 
Performance Management in ‘Big Data’ Applications
Performance Management in ‘Big Data’ ApplicationsPerformance Management in ‘Big Data’ Applications
Performance Management in ‘Big Data’ ApplicationsMichael Kopp
 
Evolution of the DBA to Data Platform Administrator/Specialist
Evolution of the DBA to Data Platform Administrator/SpecialistEvolution of the DBA to Data Platform Administrator/Specialist
Evolution of the DBA to Data Platform Administrator/SpecialistTony Rogerson
 
Etu L2 Training - Hadoop 企業應用實作
Etu L2 Training - Hadoop 企業應用實作Etu L2 Training - Hadoop 企業應用實作
Etu L2 Training - Hadoop 企業應用實作James Chen
 
Processing Drone data @Scale
Processing Drone data @ScaleProcessing Drone data @Scale
Processing Drone data @ScaleDr Hajji Hicham
 
Database.management.system.june.2012
Database.management.system.june.2012Database.management.system.june.2012
Database.management.system.june.2012NATHEEN
 
Thomas risberg mongosv-2012-spring-data-cloud-foundry
Thomas risberg mongosv-2012-spring-data-cloud-foundryThomas risberg mongosv-2012-spring-data-cloud-foundry
Thomas risberg mongosv-2012-spring-data-cloud-foundrytrisberg
 
BW Tech Meetup: Hadoop and The rise of Big Data
BW Tech Meetup: Hadoop and The rise of Big Data BW Tech Meetup: Hadoop and The rise of Big Data
BW Tech Meetup: Hadoop and The rise of Big Data Mindgrub Technologies
 

Semelhante a Migrate (20)

Distributed data mining
Distributed data miningDistributed data mining
Distributed data mining
 
Linking data without common identifiers
Linking data without common identifiersLinking data without common identifiers
Linking data without common identifiers
 
Pinterest的数据库分片架构
Pinterest的数据库分片架构Pinterest的数据库分片架构
Pinterest的数据库分片架构
 
Intro to Big Data and NoSQL
Intro to Big Data and NoSQLIntro to Big Data and NoSQL
Intro to Big Data and NoSQL
 
Ml pluss ejan2013
Ml pluss ejan2013Ml pluss ejan2013
Ml pluss ejan2013
 
Introduction to Apache Accumulo
Introduction to Apache AccumuloIntroduction to Apache Accumulo
Introduction to Apache Accumulo
 
Migrate
MigrateMigrate
Migrate
 
Django and Neo4j - Domain modeling that kicks ass
Django and Neo4j - Domain modeling that kicks assDjango and Neo4j - Domain modeling that kicks ass
Django and Neo4j - Domain modeling that kicks ass
 
Performance Management in ‘Big Data’ Applications
Performance Management in ‘Big Data’ ApplicationsPerformance Management in ‘Big Data’ Applications
Performance Management in ‘Big Data’ Applications
 
Evolution of the DBA to Data Platform Administrator/Specialist
Evolution of the DBA to Data Platform Administrator/SpecialistEvolution of the DBA to Data Platform Administrator/Specialist
Evolution of the DBA to Data Platform Administrator/Specialist
 
No Sql
No SqlNo Sql
No Sql
 
Etu L2 Training - Hadoop 企業應用實作
Etu L2 Training - Hadoop 企業應用實作Etu L2 Training - Hadoop 企業應用實作
Etu L2 Training - Hadoop 企業應用實作
 
Drill njhug -19 feb2013
Drill njhug -19 feb2013Drill njhug -19 feb2013
Drill njhug -19 feb2013
 
Processing Drone data @Scale
Processing Drone data @ScaleProcessing Drone data @Scale
Processing Drone data @Scale
 
Migrate
MigrateMigrate
Migrate
 
Database.management.system.june.2012
Database.management.system.june.2012Database.management.system.june.2012
Database.management.system.june.2012
 
Spark
SparkSpark
Spark
 
Thomas risberg mongosv-2012-spring-data-cloud-foundry
Thomas risberg mongosv-2012-spring-data-cloud-foundryThomas risberg mongosv-2012-spring-data-cloud-foundry
Thomas risberg mongosv-2012-spring-data-cloud-foundry
 
BW Tech Meetup: Hadoop and The rise of Big Data
BW Tech Meetup: Hadoop and The rise of Big Data BW Tech Meetup: Hadoop and The rise of Big Data
BW Tech Meetup: Hadoop and The rise of Big Data
 
Bw tech hadoop
Bw tech hadoopBw tech hadoop
Bw tech hadoop
 

Último

🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 

Último (20)

🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 

Migrate

  • 2. Coding & Development Getting It Into Drupal With Migrate Presented by drewish (Andrew Morton) drewish@katherinehouse.com Wednesday, March 21, 12
  • 3. So You’ve Got This Old Website... Wednesday, March 21, 12 Let’s do some shows of hands on what people are doing right now. Feeds? Custom scripts? Intern data entry? How many just know you’re going to have to in the next 6-months.
  • 4. My Goals • Give you mental framework to understand Migrate. • Step through the basics of building a migration. • Convince to use Migrate rather than custom one-off scripts and/or add Migrate support to your modules. Wednesday, March 21, 12 Put another tool in your toolbox... and just talk you into using feeds. Migrate has lots of pieces that are badly named making it harder to understand.
  • 5. Migrate 2.0 • Powerful object oriented framework for moving content into Drupal. • Minimal UI, primarily code based. • Steep learning curve. Wednesday, March 21, 12 I’ve been using Migrate for almost a year and was annoying enough in the issue queue that the just made me a maintainer. <See if Mike and Moshe are in the crowd and introduce them> Explain the differences between v2 and v1. aka migraine module, but hopefully this talk will help.
  • 6. Wednesday, March 21, 12 There’s a basic UI and great drush support. I’m going to ignore them because of time constraints.
  • 7. Migrate 2.0 • Drupal 6 requires autoload and dbtng modules. So the code is very similar in 6 and 7. • Migrate Extras provides support for many contrib modules. • The most comprehensive and up-to-date documentation is the beer.inc and wine.inc examples. Wednesday, March 21, 12 Well these slides are really the best... but the might get out of date.
  • 8. Why not just use Feeds? • If it does what you need, use it. It’s much easier to setup. • Migrate is performant, and more flexible but requires that you write code to map fields. • Feeds doesn’t work well if you’ve got different content types that need to reference each other. Wednesday, March 21, 12 Get asked this a lot. I’m pragmatic, use the best tool.
  • 10. Source & Destination Source Destination Field 1 Field 1 Field 2 Field 2 Field 3 Field 3 Field ID ID Wednesday, March 21, 12
  • 11. Source • Interface to your existing data (SQL, CSV, XML, JSON). • Provides a list of fields and descriptions. • Responsible for iterating over rows. Wednesday, March 21, 12
  • 12. Destination • Responsible for writing a specific type of data to Drupal, e.g. Node, User, or other Entity, but could be something like a SQL row. • Creates one Destination record for each Source record. Wednesday, March 21, 12 Knows how to save it... user_save(), node_save(), entity_save(), db_insert(), etc. So, if you’re creating users and profiles, you’ll need to do it in two migrations.
  • 13. Map the Fields Source Destination Field 1 Field Mapping Field 1 Field 2 Field 2 Field 3 Field 3 Field ID Field Mapping ID Wednesday, March 21, 12 With these pieces you’ve basically got feeds.
  • 14. Field Mappings Source Destination ID Name Age Other entity_id field_age field_name 1 Larry 34 blah 32 34 Larry 2 Curly 54 33 54 Curly 4 Moe 47 junk 34 47 Moe Field Mappings Source Destination Name field_name Age field_age Other NULL Wednesday, March 21, 12
  • 15. Field Mappings • Links a source field to a destination field. • Has some basic functions to transform values splitting on separators, etc. • Holds additional arguments to pass on to the destination field. Wednesday, March 21, 12 Might skip over the source id lookup since we haven’t really talked about migration maps yet.
  • 16. Migration Map Source Destination Field 1 Field Mapping Field 1 Field 2 Field 2 Field 3 Field 3 Field ID Field Mapping ID Map Wednesday, March 21, 12 Now we need to do a little more than what Feeds provides. Lets track IDs so when we import users and articles we can attribute the articles to the correct user.
  • 17. Map • Connects the Source and Destination IDs allowing translation between them. • Tracks the keys’ schema format. • Allows a migration to re-run and update existing records. • Allows imported records to be deleted during a rollback. Wednesday, March 21, 12 Also provides some other benefits. Composite keys are supported.
  • 18. Migration Migration Source Destination Field 1 Field Mapping Field 1 Field 2 Field 2 Field 3 Field 3 Field ID Field Mapping ID Map prepareRow(), prepare(), complete() Wednesday, March 21, 12 I’m going to ignore those three little functions for now but I just wanted to put them on here so you can visualize where they live.
  • 19. Migration • Sets up all the necessary pieces: Source, Destination, Map and Field Mappings. • May provide logic for skipping over rows during the migration. • May alter the entities during the migration. Wednesday, March 21, 12 Your class that glues all the parts together.
  • 20. Field Handlers Migration Source Destination Field 1 Field Mapping Field 1 Field 2 Field 3 Field Handler Field ID Field Mapping Field 2 Field Handler Field 3 Field Handler ID Map prepareRow(), prepare(), complete() Wednesday, March 21, 12 If you think about the way the data would be coming out of the Source it’ll be “flat” values like strings or integers. Drupal fields are typically nested arrays and something needs to know the format of those arrays, hence the field handler.
  • 21. Field Handlers • Handles the details of converting the Source value into the structure that Drupal understands. • Turns $row->bar = “foo” into $entity->field_bar[‘und’][0][‘value’] = “foo” • Might pull additional data out of arguments. Wednesday, March 21, 12
  • 22. Destination Handler Migration Source Destination Field 1 Field Mapping Field 1 Field 2 Field 3 Field Handler Field ID Field Mapping Field 2 Field Handler Field 3 Field Handler ID Map Destination prepareRow(), prepare(), complete() Handler(s) Wednesday, March 21, 12
  • 23. Destination Handler • “Magically” extends an existing destination and adds functionality, e.g. MigrateCommentNodeHandler adds a comment status field to nodes. • Contrib maintainers might need to create these. Wednesday, March 21, 12
  • 25. Basic Migrate Module • Create a new module to so you can disable it once the site launches. • Implement hook_migrate_api() in the .module file. • Create a class that extends Migration and in the constructor setup the Source, Destination, Map and Field Mappings. • Register the class’s file in the .info file. Wednesday, March 21, 12 If I’m being lazy and it’s only a single migration class I’ll just throw it in the .module file.
  • 26. Migration Class • Setup the Source, Destination, Map and Field Mappings in the constructor: class BasicExample extends Migration { public function __construct() { parent::__construct(); $this->source = ???; $this->destination = ???; $this->map = ???; $this->addFieldMapping(???, ???); } } Wednesday, March 21, 12 You’ll probably have more than one Field Mapping.
  • 27. SQL Source // inside __construct() $query = db_select('migrate_example_beer_topic', 'met') ->fields('met', array('style', 'details', 'style_parent', 'region', 'hoppiness')) ->orderBy('style_parent', 'ASC'); $this->source = new MigrateSourceSQL($query); Wednesday, March 21, 12 Able to extract the field names from the query. Descriptions are optional.
  • 28. Or a CSV Source // The definition of the columns. Keys are integers, // values are an array of field name then description. $columns = array(   0 => array('cvs_uid', 'Id'),   1 => array('email', 'Email'),   2 => array('name', 'Name'),   3 => array('date', 'Date'), ); // Instantiate the class using the path to the CSV // file and the columns. $path = 'path/relative/to/drupal/root/your_file.csv'; $this->source = new MigrateSourceCSV($path, $columns); Wednesday, March 21, 12 The CSV source can actually use the header row as column names but I’m not going to demonstrate that.
  • 29. Other Sources • There are also classes for importing content from XML and JSON. • Lots of variation among sources so expect to do some tweaking. Wednesday, March 21, 12
  • 30. Source Base Classes • If you can fetch IDs separately from values: • Use MigrateSourceList as a source • Implement MigrateList for fetching counts and IDs, and MigrateItem for fetching values • If everything is in a single file with IDs mixed in: • Use MigrateSourceMultiItems as a source • Implement MigrateItems for extracting IDs and values Wednesday, March 21, 12 I don’t really want to get too deep into this. I’m mentioning them so you’ll know they’re here when you discover you need them.
  • 31. Migration Map // inside __construct() $this->map = new MigrateSQLMap($this->machineName, // You’ve got to describe your id’s schema. array( 'style' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, ) ), // Most Destinations provide a helper function: MigrateDestinationTerm::getKeySchema() ); Wednesday, March 21, 12
  • 32. Destinations // inside __construct() // Create terms... $this->destination = new MigrateDestinationTerm('example_beer_styles'); // ...or nodes... $this->destination = new MigrateDestinationNode('article'); // ...or $this->destination = new MigrateDestinationUser(); Wednesday, March 21, 12
  • 33. Field Mappings // inside __construct() // Can be as simple as this… $this->addFieldMapping('dest_name', 'source_name'); // …or you can chain options onto it… $this->addFieldMapping('dest_name') ->defaultValue(1); // Lets pretend we already setup $arguments. $this->addFieldMapping('field_favbeers', 'beers') ->separator('|') ->arguments($arguments); Wednesday, March 21, 12
  • 34. Field Mapping Arguments • Often used to pass multiple source fields into a single destination field. • First argument will be the teaser field, the second argument will always be one: $this->addFieldMapping('body', 'body') ->arguments(array( 'summary' => array('source_field' => 'teaser'), 'format' => 1 )); Wednesday, March 21, 12 By default the values passed into the arguments will be used as literals. If you use that wacky array syntax it’ll replace it with the value from that field on the current row.
  • 35. Field Mapping Arguments $path = drupal_get_path('module', 'migrate_example'); // You could use the helper... $arguments = MigrateFileFieldHandler::arguments( $path, 'file_copy', FILE_EXISTS_RENAME, NULL, array('source_field' => 'image_alt')); $this->addFieldMapping('field_image', 'image') ->arguments($arguments); // Or skip it and end up with more readable code: $this->addFieldMapping('field_image', 'image') ->arguments(array( 'source_path' => $path, 'alt' => array('source_field' => 'image_alt'), )); Wednesday, March 21, 12 So two versions that do the same thing. I’m showing you this to demonstrate that some of the helpers actually obscure the functionality with out adding much value.
  • 36. Field Mapping Source Migrations • When you have an ID value from the old system and need to look up the new ID from the Migration Map: $this->addFieldMapping('uid', 'author_id') ->sourceMigration('BeerUser') • Add a dependency to make sure the other migration runs first: $this->dependencies = array('BeerUser'); Wednesday, March 21, 12
  • 37. But Wait, There’s More! • You can implement methods to customize the process: prepareRow(), prepare(), complete(). • Yeah, it might be hard to remember which prepare does what. Wednesday, March 21, 12
  • 38. prepareRow($row) • Passes in the source row as an object so you can make modifications. • Can indicate that a row should be skipped over during the import by returning FALSE. • Add or change field values by modifying the properties: $row->first = drupal_strtoupper($row->first); $row->created = strtotime($row->access); Wednesday, March 21, 12 Need to mention that if you add a field in prepareRow() you should really add it to the Source’s field list.
  • 39. prepare($entity, $row) • Passes in the entity object with properties populated by field mappings, and the source row. • Last chance to make changes before the entity is saved. • If you have an unsupported field type you can manually populate it here: $entity->field_foo[‘und’][0][‘foo’] = $row->foo; Wednesday, March 21, 12
  • 40. complete($ent, $row) • Passes in the saved entity (with any ID values from auto increment fields) and the source row. • This is the place if you need to update other records to reference the new entity. • If you’re calling node_save() or entity_save() on the record you just imported, you’re probably doing something wrong. Wednesday, March 21, 12
  • 41. Dealing With Circular Dependencies • Break them by using stubs. • Specify a sourceMigration(‘BeerUser’) on the ID’s field mapping. • Add createStub($migration, $source_key) to BeerUser which creates an empty record and returns the new id. • When BeerUser runs it’ll update the stub and fill it with the real values. Wednesday, March 21, 12 Basically one migration asks another to look up the ID mapping, if it doesn’t exists the second migration will create an empty record to get an ID so the first migration can complete. Then when the second migration runs it will update the dummy record that was created earlier.
  • 42. Import Flow Migration Source Destination Field 1 Field Mapping Field 1 Field 2 Field 3 Field Handler Field ID Field Mapping Field 2 Field Handler Field 3 Field Handler ID Map Destination prepareRow(), prepare(), complete() Handler(s) Wednesday, March 21, 12
  • 43. Import Flow • Source iterates until it locates an appropriate record, then calls the Migration’s prepareRow($row) letting you modify or reject the data in $row. • Migration applies the Field Mappings and the Field Handlers to convert the data in $row into $entity. • Migration calls prepare($entity, $row) letting you modify the final entity using data from the Source’s row. • Destination saves the entity. • Migration records the IDs into the Map then calls complete() so you can see the entity’s final ID. Wednesday, March 21, 12
  • 44. Supporting Migrate in Contrib • If you’re creating new objects (e.g. Webform Submissions) write a Destination. • If you’re writing field modules write a Field Handler. Wednesday, March 21, 12
  • 45. Creating Destinations • Hopefully you won’t need to… • If you’re working with entities created by the Entity API make sure you look at: http://drupal.org/node/1168196 Wednesday, March 21, 12
  • 46. Creating Field Handlers • Look at extending MigrateSimpleFieldHandler for single value fields. • In the constructor register your field types. • In prepare() convert the value into the format your field requires. • Optionally, in complete() handle any followup tasks that require the entity’s ID. Wednesday, March 21, 12
  • 47. Questions? Migration Source Destination Field 1 Field Mapping Field 1 Field 2 Field 3 Field Handler Field ID Field Mapping Field 2 Field Handler Field 3 Field Handler ID Map Destination prepareRow(), prepare(), complete() Handler(s) Wednesday, March 21, 12
  • 48. What did you think? Locate this session on the DrupalCon Denver website http://denver2012.drupal.org/program Click the “Take the Survey” link. Thank You! Wednesday, March 21, 12