Importing Data From Sinatra App To Django App
Since I have recently ported this site to Django (see here), I realized that it would be nice to have my existing blog entries and comments ported over as well. I decided to basically just copy them from one database to another. While this would get the existing posts and comments, it would not move new ones over. That's fine. I just want some data in the Django version.
So my approach is relatively simple. Since both data models match (with the exception of table names), why not just use ActiveRecord? There are other ways, obviously, but I thought that this might be a nice exercise.
Here's the basic layout of my DataConversion project
DataConversion
lib
Source
source_base.rb
post.rb
comment.rb
Destination
destination_base.rb
post.rb
comment.rb
main.rb
Essentially, the concept here is to model each database seperately, but to allow them to interact through active record.
Here are the base classes:
#The destination base class
module Destination
class DestinationBase < ActiveRecord::Base
establish_connection(
:adapter => "mysql",
:username => "username",
:password => "password",
:database => "the_dest_db")
self.abstract_class = true
end
end
#The source base class
module Source
class SourceBase < ActiveRecord::Base
establish_connection(
:adapter => "mysql",
:username => "username",
:password => "password",
:database => "the_source_db")
self.abstract_class = true
end
end
Really all each does is set up it's own connection and declare itself abstract.
Here are the models:
#The destination models
module Destination
class Post < DestinationBase
self.table_name = "blog_post"
has_many :comments
end
end
module Destination
class Comment < DestinationBase
self.table_name = "blog_comment"
belongs_to :post
end
end
#The source models
module Source
class Post < SourceBase
has_many :comments
end
end
module Source
class Comment < SourceBase
belongs_to :post
end
end
Pretty straighforward, yes? The thing to note is that the Destination models specify a table name, since it is non-standard for ActiveRecord.
Now, here's the main.rb file
require 'rubygems'
require 'activerecord'
['source_base', 'post', 'comment'].each {|f| require File.join(File.dirname(__FILE__), "source", f)}
['destination_base', 'post', 'comment'].each {|f| require File.join(File.dirname(__FILE__), "destination", f)}
puts "Reading source posts ... "
puts "\n"
src = Source::Post.all
puts "Creating destination post from source post ... "
puts "\n"
src.each do |p|
dest = Destination::Post.new
p.attributes.select {|attr, value| attr != "id"}.each {|attr, value| eval("dest.#{attr}=p.#{attr}") }
dest.save!
p.comments.each do |c|
dest_comment = Destination::Comment.new
c.attributes.select {|attr, value| attr != "id" || attr != "post_id"}.each {|attr, value| eval("dest_comment.#{attr}=c.#{attr}")}
dest_comment.post = dest
dest_comment.save!
end
end
puts "Done!"
So, in the main app, we load all of the source posts and iterate through them while creating new destination posts by copying their attribute values (and ignoring ids). We do the same with the comments for each, while also ignoring the source post id and making sure to assign it to the newly created destination post.


No comments have been posted.