neo4apis-activerecord 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 958a75dd44231361bc7386645f422d8041a49b00
4
- data.tar.gz: 7805c98e8aaed169ce2f9e438a485fa12519652a
3
+ metadata.gz: ab9aecb11a9464f24fea4306dd70129fa149ef80
4
+ data.tar.gz: 3dfa664c481fa064e3b4ecaee0db545849f5a494
5
5
  SHA512:
6
- metadata.gz: 0a9da16b04590e66e99d5aed580847df688cd39d3ed01e39ac729997bf8954ac76e58d9ff3e03992df09fa46f26682737f5483fb02924f639f4091dfdc4e7b3e
7
- data.tar.gz: 96d2c984a9e98bd2133b741737be303a47c7c8ad807afe00a859e76d275dbb7759ad242b4f7e58ed60daeae162db4009be12cc21783721a36402ecf72d80f80e
6
+ metadata.gz: 9ee71960a9de10387b975fac9cb76948398f73e1599318f4e1ff7f2133be15ed47db5858c57f716cc5b4e2736ff5efed77a16ae3ae65e14256c4cce85e349608
7
+ data.tar.gz: ea45c3c56cbbd9e114b5d2a5a46b833968d3a6cbabff9839ecc9fbaba1964ba7e555717f3eea962a883a9a181593171e115da2f9404c9729f4786feda51f9cc0
data/README.md CHANGED
@@ -0,0 +1,55 @@
1
+ # neo4apis-activerecord
2
+
3
+ **The easiest and quickest way to copy data from PostgreSQL / mySQL / sqlite to Neo4j**
4
+
5
+ ## How to run:
6
+
7
+ Without existing ActiveRecord application:
8
+
9
+ neo4apis activerecord all_tables --import-all-associations --identify-model
10
+
11
+ or
12
+
13
+ neo4apis activerecord tables posts comments --import-all-associations --identify-model
14
+
15
+ With existing ActiveRecord application:
16
+
17
+ neo4apis activerecord all_models --import-all-associations
18
+
19
+ or
20
+
21
+ neo4apis activerecord models Post Comment --import-all-associations
22
+
23
+ ## Installation
24
+
25
+ Using rubygems:
26
+
27
+ gem install neo4apis-activerecord
28
+
29
+ ## How it works
30
+
31
+ [ActiveRecord](http://guides.rubyonrails.org/active_record_basics.html) is a [ORM](http://en.wikipedia.org/wiki/Object-relational_mapping) for ruby. `neo4apis-activerecord` uses ActiveRecord models which are either found in an existing ruby app or generated from table structures. The models are then introspected to create nodes (from tables) and relationships (from associations) in neo4j. The neo4apis library is used to load data efficiently in batches.
32
+
33
+ ## Options
34
+
35
+ For a list of all options run:
36
+
37
+ neo4apis activerecord --help
38
+
39
+ ### `--identify-model`
40
+
41
+ The `--identify-model` option looks for tables' names/primay keys/foreign keys automatically. Potential options are generated and the database is examined to find out which fits.
42
+
43
+ As an example: for a table of posts the following possibilities would checked:
44
+
45
+ * Names: `posts`, `post`, `Posts`, or `Post`
46
+ * Primary keys: `id`, `post_id`, `PostId`, or `uuid`
47
+ * Foreign keys: `author_id` or `AuthorId` will be assumed to go to a table of authors (with a name identified as above)
48
+
49
+ ### `--import-belongs-to`
50
+ ### `--import-has-many`
51
+ ### `--import-has-one`
52
+ ### `--import-all-associations`
53
+
54
+ Either specify that a certain class of associations be imported from ActiveRecord models or specify all with `--import-all-associations`
55
+
@@ -8,23 +8,25 @@ module Neo4Apis
8
8
  class ActiveRecord < Thor
9
9
  class_option :config_path, type: :string, default: 'config/database.yml'
10
10
 
11
- class_option :import_associations, type: :boolean, default: false
11
+ class_option :import_all_associations, type: :boolean, default: false, desc: 'Shortcut for --import-belongs-to --import-has-many --import-has-one'
12
12
  class_option :import_belongs_to, type: :boolean, default: nil
13
13
  class_option :import_has_one, type: :boolean, default: nil
14
14
  class_option :import_has_many, type: :boolean, default: nil
15
15
 
16
- class_option :guess_model, type: :boolean, default: false
16
+ class_option :identify_model, type: :boolean, default: false, desc: 'Identify table name, primary key, and foreign keys automatically'
17
+
18
+ class_option :startup_environment, type: :string, default: './config/environment.rb', desc: 'Script that will be run before import. Needs to establish an ActiveRecord connection'
17
19
 
18
20
  class_option :active_record_config_path, type: :string, default: './config/database.yml'
19
21
  class_option :active_record_environment, type: :string, default: 'development'
20
22
 
21
- desc 'tables MODELS_OR_TABLE_NAMES', 'Import SQL specified tables'
23
+ desc 'tables MODELS_OR_TABLE_NAMES', 'Import specified SQL tables'
22
24
  def tables(*models_or_table_names)
23
25
  setup
24
26
 
25
27
  model_classes = models_or_table_names.map(&method(:get_model))
26
28
 
27
- puts "Importing tables: " + model_classes.map(&:table_name).join(', ')
29
+ puts 'Importing tables: ' + model_classes.map(&:table_name).join(', ')
28
30
 
29
31
  model_classes.each do |model_class|
30
32
  ::Neo4Apis::ActiveRecord.model_importer(model_class)
@@ -39,19 +41,28 @@ module Neo4Apis
39
41
  end
40
42
  end
41
43
 
44
+ desc 'models MODELS_OR_TABLE_NAMES', 'Import specified ActiveRecord models'
45
+ def models(*models_or_table_names)
46
+ tables(*models_or_table_names)
47
+ end
48
+
42
49
  desc 'all_tables', 'Import all SQL tables'
43
50
  def all_tables
44
- setup
51
+ tables(*::ActiveRecord::Base.connection.tables)
52
+ end
53
+
54
+ desc 'all_models', 'Import SQL tables using defined '
55
+ def all_models
56
+ Rails.application.eager_load!
45
57
 
46
- models(*::ActiveRecord::Base.connection.tables)
58
+ tables(ActiveRecord::Base.descendants)
47
59
  end
48
60
 
49
61
  private
50
62
 
51
63
  def setup
52
- if File.exist?('config/environment.rb')
53
- # Rails
54
- require './config/environment'
64
+ if File.exist?(options[:startup_environment])
65
+ require options[:startup_environment]
55
66
  else
56
67
  ::ActiveRecord::Base.establish_connection(active_record_config)
57
68
  end
@@ -67,16 +78,18 @@ module Neo4Apis
67
78
  end
68
79
 
69
80
  def import_association?(type)
70
- options[:"import_#{type}"].nil? ? options[:import_associations] : options[:"import_#{type}"]
81
+ options[:"import_#{type}"].nil? ? options[:import_all_associations] : options[:"import_#{type}"]
71
82
  end
72
83
 
73
84
 
74
85
  def get_model(model_or_table_name)
86
+ return model_or_table_name if model_or_table_name.is_a?(ActiveRecord::Base)
87
+
75
88
  get_model_class(model_or_table_name).tap do |model_class|
76
- if options[:guess_model]
77
- apply_guessed_table_name!(model_class)
78
- apply_guessed_primary_key!(model_class)
79
- apply_guessed_model_associations!(model_class)
89
+ if options[:identify_model]
90
+ apply_identified_table_name!(model_class)
91
+ apply_identified_primary_key!(model_class)
92
+ apply_identified_model_associations!(model_class)
80
93
  end
81
94
  end
82
95
  end
@@ -89,7 +102,7 @@ module Neo4Apis
89
102
  Object.const_set(model_class, Class.new(::ActiveRecord::Base))
90
103
  end
91
104
 
92
- def apply_guessed_model_associations!(model_class)
105
+ def apply_identified_model_associations!(model_class)
93
106
  model_class.columns.each do |column|
94
107
  match = column.name.match(/^(.*)(_id|Id)$/)
95
108
  next if not match
@@ -97,21 +110,23 @@ module Neo4Apis
97
110
  begin
98
111
  base = match[1].tableize
99
112
 
100
- model_class.belongs_to base.singularize.to_sym, foreign_key: column.name, class_name: base.classify if guessed_table_name(base.classify)
113
+ if identified_table_name(base.classify) && model_class.name != base.classify
114
+ model_class.belongs_to base.singularize.to_sym, foreign_key: column.name, class_name: base.classify
115
+ end
101
116
  rescue NameError
102
117
  end
103
118
  end
104
119
  end
105
120
 
106
- def apply_guessed_table_name!(model_class)
107
- guess = guessed_table_name(model_class.name)
108
- model_class.table_name = guess if guess
121
+ def apply_identified_table_name!(model_class)
122
+ identity = identified_table_name(model_class.name)
123
+ model_class.table_name = identity if identity
109
124
  end
110
125
 
111
- def apply_guessed_primary_key!(model_class)
126
+ def apply_identified_primary_key!(model_class)
112
127
  name = model_class.name
113
- guess = (model_class.column_names & ['id', name.foreign_key, name.foreign_key.classify, 'uuid']).first
114
- model_class.primary_key = guess if guess
128
+ identity = (model_class.column_names & ['id', name.foreign_key, name.foreign_key.classify, 'uuid']).first
129
+ model_class.primary_key = identity if identity
115
130
  end
116
131
 
117
132
 
@@ -122,7 +137,7 @@ module Neo4Apis
122
137
 
123
138
  private
124
139
 
125
- def guessed_table_name(model_name)
140
+ def identified_table_name(model_name)
126
141
  (::ActiveRecord::Base.connection.tables & [model_name.tableize, model_name.classify, model_name.tableize.singularize, model_name.classify.pluralize]).first
127
142
  end
128
143
  end
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'neo4apis-activerecord'
6
- s.version = '0.3.0'
6
+ s.version = '0.4.0'
7
7
  s.required_ruby_version = '>= 1.9.1'
8
8
 
9
9
  s.authors = 'Brian Underwood'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neo4apis-activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Underwood