activerecord-dbt 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 897ffab9f05715634ea7eb0ef68be9c70e8d305458657696fe544255f17293c9
4
- data.tar.gz: f82f9f7b02c592572077f3ba41bf0920ae0abb831de065b707d107124080353d
3
+ metadata.gz: c7948bb8cc4c14d07c3fca2855b20957a2871c54dd67149fb178029fa93f6f09
4
+ data.tar.gz: c8146bfcd3ffa762f16889a79750807ab1e72986e49f34069ac043fe8c89d5f0
5
5
  SHA512:
6
- metadata.gz: cd87b1c4a5ba3e97aad5320f58eb9151e14ff8752b93519b0b14314b9ba872b48afee79e93e09de813898ccf83dc3d41a0d64d07277c1e8cf7413dabd93a7fd2
7
- data.tar.gz: 829ff19c802bc18c7e721ede97beff805e26e9642382153a64ececb21e7f5b6512cab9f226e1ef3c7ca51399a9ec4604cf7b3b1a1f61e237e74a99327b12429e
6
+ metadata.gz: a2d3ce1aa15cafbd0bb6f282d5faa64f6319d669a38a8dde20b04af3cccf12a21e16fa22cf6f7b87b245dd094bad296de2dd22bd027db047b2ed845cc7de2b8a
7
+ data.tar.gz: 6097b5f0b25324679e012d4a16833afba17514f2ebb82eabe778ae510bc8f283c280dd3d6916b2a3220092c63c7827c56b4b0660f14caa6f1b210a496dff7cdc
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # ActiveRecord::Dbt
2
2
 
3
- `ActiveRecord::Dbt` generates dbt files from the information of the database connected via ActiveRecord.
3
+ [![Gem Version](https://badge.fury.io/rb/activerecord-dbt.svg)](https://badge.fury.io/rb/activerecord-dbt)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/ef9a0a71c73dae7b8156/maintainability)](https://codeclimate.com/github/yamotech/activerecord-dbt/maintainability)
5
+ [![Ruby CI](https://github.com/yamotech/activerecord-dbt/actions/workflows/ruby-ci.yml/badge.svg)](https://github.com/yamotech/activerecord-dbt/actions/workflows/ruby-ci.yml)
6
+
7
+ `ActiveRecord::Dbt` generates [dbt](https://www.getdbt.com/) files from the information of the database connected via ActiveRecord.
4
8
 
5
9
  Currently, it can generate `yaml` files for `sources` and `models` files for `staging`.
6
10
 
@@ -50,10 +54,28 @@ Configuration | Description
50
54
  --------- | ---------
51
55
  config_directory_path | The path to the directory where files generated by `bin/rails generate active_record:dbt:*` are stored. The default is `lib/dbt`.
52
56
  export_directory_path | The path to the directory where configuration files are stored. The default is `doc/dbt`.
57
+ dwh_platform | Specify the data warehouse platform to which dbt connects. The default is `bigquery`.
53
58
  data_sync_delayed | Indicates whether there is a data delay. If set to `true`, `severity: warn` is applied to the `relationships` test. The default is `false`.
54
59
  logger | The destination for log output. The default is `Logger.new('./log/active_record_dbt.log')`.
55
60
  used_dbt_package_names | An array of `dbt` package names to use.
56
61
 
62
+ List of platforms that can currently be set with `dwh_platform`.
63
+
64
+ Data Warehouse Platform | Link
65
+ --------- | ---------
66
+ bigquery | [BigQuery enterprise data warehouse - Google Cloud](https://cloud.google.com/bigquery?hl=en)
67
+ postgres | [PostgreSQL: The world's most advanced open source database](https://www.postgresql.org/)
68
+ redshift | [Cloud Data Warehouse - Amazon Redshift - AWS](https://aws.amazon.com/redshift/)
69
+ snowflake | [The Snowflake AI Data Cloud - Mobilize Data, Apps, and AI](https://www.snowflake.com/en/)
70
+ spark | [Apache Spark™ - Unified Engine for large-scale data analytics](https://spark.apache.org/)
71
+
72
+ List of packages that can currently be set with `used_dbt_package_names`.
73
+
74
+ dbt Package Name | Link
75
+ --------- | ---------
76
+ dbt-labs/dbt-utils | [dbt-labs/dbt-utils: Utility functions for dbt projects.](https://github.com/dbt-labs/dbt-utils)
77
+ datnguye/dbterd | [datnguye/dbterd: Generate the ERD as a code from dbt artifacts](https://github.com/datnguye/dbterd)
78
+
57
79
  Example:
58
80
 
59
81
  Adjust the settings according to your environment.
@@ -294,25 +316,21 @@ sources:
294
316
  columns:
295
317
  - name: key
296
318
  description: Key
297
- meta:
298
- column_type: string
319
+ data_type: string
299
320
  tests:
300
321
  - unique
301
322
  - not_null
302
323
  - name: value
303
324
  description: Value
304
- meta:
305
- column_type: string
325
+ data_type: string
306
326
  - name: created_at
307
327
  description: Created At
308
- meta:
309
- column_type: datetime
328
+ data_type: datetime
310
329
  tests:
311
330
  - not_null
312
331
  - name: updated_at
313
332
  description: Updated At
314
- meta:
315
- column_type: datetime
333
+ data_type: datetime
316
334
  tests:
317
335
  - not_null
318
336
  - name: companies
@@ -320,29 +338,24 @@ sources:
320
338
  columns:
321
339
  - name: id
322
340
  description: id
323
- meta:
324
- column_type: integer
341
+ data_type: int64
325
342
  tests:
326
343
  - unique
327
344
  - not_null
328
345
  - name: name
329
346
  description: Write a description of the 'companies.name' column.
330
- meta:
331
- column_type: string
347
+ data_type: string
332
348
  tests:
333
349
  - not_null
334
350
  - name: establishment_date
335
351
  description: Write a description of the 'companies.establishment_date' column.
336
- meta:
337
- column_type: string
352
+ data_type: string
338
353
  - name: average_age
339
354
  description: Write a description of the 'companies.average_age' column.
340
- meta:
341
- column_type: float
355
+ data_type: float64
342
356
  - name: published
343
357
  description: Write a description of the 'companies.published' column.
344
- meta:
345
- column_type: boolean
358
+ data_type: bool
346
359
  tests:
347
360
  - not_null
348
361
  - accepted_values:
@@ -352,14 +365,12 @@ sources:
352
365
  quote: false
353
366
  - name: created_at
354
367
  description: Created At
355
- meta:
356
- column_type: datetime
368
+ data_type: datetime
357
369
  tests:
358
370
  - not_null
359
371
  - name: updated_at
360
372
  description: Updated At
361
- meta:
362
- column_type: datetime
373
+ data_type: datetime
363
374
  tests:
364
375
  - not_null
365
376
  - name: posts
@@ -367,15 +378,13 @@ sources:
367
378
  columns:
368
379
  - name: id
369
380
  description: ID
370
- meta:
371
- column_type: integer
381
+ data_type: int64
372
382
  tests:
373
383
  - unique
374
384
  - not_null
375
385
  - name: user_id
376
386
  description: User
377
- meta:
378
- column_type: integer
387
+ data_type: int64
379
388
  tests:
380
389
  - not_null
381
390
  - relationships:
@@ -385,28 +394,23 @@ sources:
385
394
  relationship_type: many-to-one
386
395
  - name: title
387
396
  description: Title
388
- meta:
389
- column_type: string
397
+ data_type: string
390
398
  - name: content
391
399
  description: Content
392
- meta:
393
- column_type: text
400
+ data_type: string
394
401
  - name: created_at
395
402
  description: Post Created At
396
- meta:
397
- column_type: datetime
403
+ data_type: datetime
398
404
  tests:
399
405
  - not_null
400
406
  - name: updated_at
401
407
  description: Post Updated At
402
- meta:
403
- column_type: datetime
408
+ data_type: datetime
404
409
  tests:
405
410
  - not_null
406
411
  - name: status
407
412
  description: Write a description of the 'posts.status' column.
408
- meta:
409
- column_type: integer
413
+ data_type: int64
410
414
  tests:
411
415
  - accepted_values:
412
416
  values:
@@ -424,8 +428,7 @@ sources:
424
428
  columns:
425
429
  - name: post_id
426
430
  description: post_id
427
- meta:
428
- column_type: integer
431
+ data_type: int64
429
432
  tests:
430
433
  - not_null
431
434
  - relationships:
@@ -438,8 +441,7 @@ sources:
438
441
  message: uninitialized constant PostsTag
439
442
  - name: tag_id
440
443
  description: tag_id
441
- meta:
442
- column_type: integer
444
+ data_type: int64
443
445
  tests:
444
446
  - not_null
445
447
  - relationships:
@@ -455,15 +457,13 @@ sources:
455
457
  columns:
456
458
  - name: id
457
459
  description: id
458
- meta:
459
- column_type: integer
460
+ data_type: int64
460
461
  tests:
461
462
  - unique
462
463
  - not_null
463
464
  - name: user_id
464
465
  description: user_id
465
- meta:
466
- column_type: integer
466
+ data_type: int64
467
467
  tests:
468
468
  - unique
469
469
  - not_null
@@ -474,26 +474,22 @@ sources:
474
474
  relationship_type: one-to-one
475
475
  - name: first_name
476
476
  description: Write a description of the 'profiles.first_name' column.
477
- meta:
478
- column_type: string
477
+ data_type: string
479
478
  tests:
480
479
  - not_null
481
480
  - name: last_name
482
481
  description: Write a description of the 'profiles.last_name' column.
483
- meta:
484
- column_type: string
482
+ data_type: string
485
483
  tests:
486
484
  - not_null
487
485
  - name: created_at
488
486
  description: Created At
489
- meta:
490
- column_type: datetime
487
+ data_type: datetime
491
488
  tests:
492
489
  - not_null
493
490
  - name: updated_at
494
491
  description: Updated At
495
- meta:
496
- column_type: datetime
492
+ data_type: datetime
497
493
  tests:
498
494
  - not_null
499
495
  - name: relationships
@@ -506,15 +502,13 @@ sources:
506
502
  columns:
507
503
  - name: id
508
504
  description: id
509
- meta:
510
- column_type: integer
505
+ data_type: int64
511
506
  tests:
512
507
  - unique
513
508
  - not_null
514
509
  - name: follower_id
515
510
  description: follower_id
516
- meta:
517
- column_type: integer
511
+ data_type: int64
518
512
  tests:
519
513
  - not_null
520
514
  - relationships:
@@ -524,8 +518,7 @@ sources:
524
518
  relationship_type: many-to-one
525
519
  - name: followed_id
526
520
  description: followed_id
527
- meta:
528
- column_type: integer
521
+ data_type: int64
529
522
  tests:
530
523
  - not_null
531
524
  - relationships:
@@ -535,14 +528,12 @@ sources:
535
528
  relationship_type: many-to-one
536
529
  - name: created_at
537
530
  description: Created At
538
- meta:
539
- column_type: datetime
531
+ data_type: datetime
540
532
  tests:
541
533
  - not_null
542
534
  - name: updated_at
543
535
  description: Updated At
544
- meta:
545
- column_type: datetime
536
+ data_type: datetime
546
537
  tests:
547
538
  - not_null
548
539
  - name: schema_migrations
@@ -553,8 +544,7 @@ sources:
553
544
  columns:
554
545
  - name: version
555
546
  description: The version number of the migration.
556
- meta:
557
- column_type: string
547
+ data_type: string
558
548
  tests:
559
549
  - unique
560
550
  - not_null
@@ -563,28 +553,24 @@ sources:
563
553
  columns:
564
554
  - name: id
565
555
  description: id
566
- meta:
567
- column_type: integer
556
+ data_type: int64
568
557
  tests:
569
558
  - unique
570
559
  - not_null
571
560
  - name: name
572
561
  description: Write a description of the 'tags.name' column.
573
- meta:
574
- column_type: string
562
+ data_type: string
575
563
  tests:
576
564
  - unique
577
565
  - not_null
578
566
  - name: created_at
579
567
  description: Created At
580
- meta:
581
- column_type: datetime
568
+ data_type: datetime
582
569
  tests:
583
570
  - not_null
584
571
  - name: updated_at
585
572
  description: Updated At
586
- meta:
587
- column_type: datetime
573
+ data_type: datetime
588
574
  tests:
589
575
  - not_null
590
576
  - name: user_tags
@@ -597,15 +583,13 @@ sources:
597
583
  columns:
598
584
  - name: id
599
585
  description: id
600
- meta:
601
- column_type: integer
586
+ data_type: int64
602
587
  tests:
603
588
  - unique
604
589
  - not_null
605
590
  - name: user_id
606
591
  description: user_id
607
- meta:
608
- column_type: integer
592
+ data_type: int64
609
593
  tests:
610
594
  - not_null
611
595
  - relationships:
@@ -615,8 +599,7 @@ sources:
615
599
  relationship_type: many-to-one
616
600
  - name: tag_id
617
601
  description: tag_id
618
- meta:
619
- column_type: integer
602
+ data_type: int64
620
603
  tests:
621
604
  - not_null
622
605
  - relationships:
@@ -626,14 +609,12 @@ sources:
626
609
  relationship_type: many-to-one
627
610
  - name: created_at
628
611
  description: Created At
629
- meta:
630
- column_type: datetime
612
+ data_type: datetime
631
613
  tests:
632
614
  - not_null
633
615
  - name: updated_at
634
616
  description: Updated At
635
- meta:
636
- column_type: datetime
617
+ data_type: datetime
637
618
  tests:
638
619
  - not_null
639
620
  - name: users
@@ -649,28 +630,24 @@ sources:
649
630
  columns:
650
631
  - name: id
651
632
  description: ID
652
- meta:
653
- column_type: integer
633
+ data_type: int64
654
634
  tests:
655
635
  - unique
656
636
  - not_null
657
637
  - name: created_at
658
638
  description: User Created At
659
- meta:
660
- column_type: datetime
639
+ data_type: datetime
661
640
  tests:
662
641
  - not_null:
663
642
  where: id != 1
664
643
  - name: updated_at
665
644
  description: User Updated At
666
- meta:
667
- column_type: datetime
645
+ data_type: datetime
668
646
  tests:
669
647
  - not_null
670
648
  - name: company_id
671
649
  description: company_id
672
- meta:
673
- column_type: integer
650
+ data_type: int64
674
651
  tests:
675
652
  - relationships:
676
653
  to: source('dummy', 'companies')
@@ -863,8 +840,7 @@ models:
863
840
  columns:
864
841
  - name: profile_id
865
842
  description: profile_id
866
- meta:
867
- column_type: integer
843
+ data_type: int64
868
844
  tests:
869
845
  - unique
870
846
  - not_null
@@ -875,8 +851,7 @@ models:
875
851
  relationship_type: one-to-one
876
852
  - name: user_id
877
853
  description: user_id
878
- meta:
879
- column_type: integer
854
+ data_type: int64
880
855
  tests:
881
856
  - unique
882
857
  - not_null
@@ -887,26 +862,22 @@ models:
887
862
  relationship_type: one-to-one
888
863
  - name: first_name
889
864
  description: Write a description of the 'profiles.first_name' column.
890
- meta:
891
- column_type: string
865
+ data_type: string
892
866
  tests:
893
867
  - not_null
894
868
  - name: last_name
895
869
  description: Write a description of the 'profiles.last_name' column.
896
- meta:
897
- column_type: string
870
+ data_type: string
898
871
  tests:
899
872
  - not_null
900
873
  - name: created_at
901
874
  description: Created At
902
- meta:
903
- column_type: datetime
875
+ data_type: datetime
904
876
  tests:
905
877
  - not_null
906
878
  - name: updated_at
907
879
  description: Updated At
908
- meta:
909
- column_type: datetime
880
+ data_type: datetime
910
881
  tests:
911
882
  - not_null
912
883
 
@@ -4,6 +4,8 @@ module ActiveRecord
4
4
  module Dbt
5
5
  module Column
6
6
  class Column
7
+ include ActiveRecord::Dbt::DataType::Mapper
8
+
7
9
  attr_reader :table_name, :column, :column_test, :primary_keys
8
10
 
9
11
  delegate :name, :comment, to: :column, prefix: true
@@ -21,7 +23,7 @@ module ActiveRecord
21
23
  {
22
24
  'name' => column_name,
23
25
  'description' => description,
24
- 'meta' => { 'column_type' => column.type.to_s },
26
+ 'data_type' => data_type,
25
27
  **column_overrides.except(:tests),
26
28
  'tests' => column_test.config
27
29
  }.compact
@@ -5,17 +5,13 @@ module ActiveRecord
5
5
  module Column
6
6
  module Testable
7
7
  module AcceptedValuesTestable
8
- REQUIRED_ACCEPTED_VALUES_TESTABLE_METHODS = %i[@config column table_name column_name].freeze
8
+ extend ActiveRecord::Dbt::RequiredMethods
9
+
10
+ define_required_methods :@config, :column, :table_name, :column_name
9
11
 
10
12
  delegate :type, to: :column, prefix: true
11
13
  delegate :add_log, to: :@config
12
14
 
13
- REQUIRED_ACCEPTED_VALUES_TESTABLE_METHODS.each do |method_name|
14
- define_method(method_name) do
15
- raise NotImplementedError, "You must implement #{self.class}##{__method__}"
16
- end
17
- end
18
-
19
15
  def accepted_values_test
20
16
  return nil unless column_type == :boolean || enum_values.present?
21
17
 
@@ -5,13 +5,9 @@ module ActiveRecord
5
5
  module Column
6
6
  module Testable
7
7
  module NotNullTestable
8
- REQUIRED_NOT_NULL_TESTABLE_METHODS = %i[column].freeze
8
+ extend ActiveRecord::Dbt::RequiredMethods
9
9
 
10
- REQUIRED_NOT_NULL_TESTABLE_METHODS.each do |method_name|
11
- define_method(method_name) do
12
- raise NotImplementedError, "You must implement #{self.class}##{__method__}"
13
- end
14
- end
10
+ define_required_methods :column
15
11
 
16
12
  def not_null_test
17
13
  column.null == true ? nil : 'not_null'
@@ -5,19 +5,15 @@ module ActiveRecord
5
5
  module Column
6
6
  module Testable
7
7
  module RelationshipsTestable
8
- REQUIRED_RELATIONSHIPS_TESTABLE_METHODS = %i[@config foreign_keys column_name].freeze
9
-
10
8
  include ActiveRecord::Dbt::DbtPackage::Dbterd::Column::Testable::RelationshipsMetaRelationshipType
11
9
 
10
+ extend ActiveRecord::Dbt::RequiredMethods
11
+
12
+ define_required_methods :@config, :foreign_keys, :column_name
13
+
12
14
  delegate :source_name, :data_sync_delayed?, to: :@config
13
15
  delegate :to_table, to: :foreign_key
14
16
 
15
- REQUIRED_RELATIONSHIPS_TESTABLE_METHODS.each do |method_name|
16
- define_method(method_name) do
17
- raise NotImplementedError, "You must implement #{self.class}##{__method__}"
18
- end
19
- end
20
-
21
17
  def relationships_test
22
18
  return nil if foreign_key.blank?
23
19
 
@@ -5,13 +5,9 @@ module ActiveRecord
5
5
  module Column
6
6
  module Testable
7
7
  module UniqueTestable
8
- REQUIRED_UNIQUE_TESTABLE_METHODS = %i[table_name column_name primary_keys].freeze
8
+ extend ActiveRecord::Dbt::RequiredMethods
9
9
 
10
- REQUIRED_UNIQUE_TESTABLE_METHODS.each do |method_name|
11
- define_method(method_name) do
12
- raise NotImplementedError, "You must implement #{self.class}##{__method__}"
13
- end
14
- end
10
+ define_required_methods :table_name, :column_name, :primary_keys
15
11
 
16
12
  def unique_test
17
13
  unique? ? 'unique' : nil
@@ -8,6 +8,7 @@ module ActiveRecord
8
8
  include Singleton
9
9
 
10
10
  include ActiveRecord::Dbt::Configuration::DataSync
11
+ include ActiveRecord::Dbt::Configuration::DwhPlatform
11
12
  include ActiveRecord::Dbt::Configuration::Logger
12
13
  include ActiveRecord::Dbt::Configuration::Parser
13
14
  include ActiveRecord::Dbt::Configuration::UsedDbtPackage
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Dbt
5
+ module Configuration
6
+ module DwhPlatform
7
+ extend ActiveRecord::Dbt::RequiredMethods
8
+
9
+ define_required_methods :source_config_path
10
+
11
+ def dwh_platform=(dwh_platform)
12
+ @dwh_platform = validate_dwh_platform(dwh_platform)
13
+ end
14
+
15
+ def dwh_platform
16
+ @dwh_platform || (raise DwhPlatformIsNullError, "'dwh_platform' is required in '#{source_config_path}'.")
17
+ end
18
+
19
+ private
20
+
21
+ def validate_dwh_platform(dwh_platform)
22
+ return dwh_platform if selectable_dwh_platforms.include?(dwh_platform)
23
+
24
+ raise DoesNotExistOnTheDwhPlatformError, [
25
+ "'#{dwh_platform}' does not exist on the DWH platform.",
26
+ "Please specify one of the following: #{selectable_dwh_platforms.join(', ')}."
27
+ ].join(' ')
28
+ end
29
+
30
+ def selectable_dwh_platforms
31
+ @selectable_dwh_platforms ||= ActiveRecord::Dbt::DataType::Mapper::RUBY_TO_DWH_PLATFORM_TYPE_MAP.keys
32
+ end
33
+
34
+ class DoesNotExistOnTheDwhPlatformError < StandardError; end
35
+ class DwhPlatformIsNullError < StandardError; end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Dbt
5
+ module DataType
6
+ module DwhPlatform
7
+ module ApacheSpark
8
+ # TODO: I have not tried it. I don't know if this is the correct data_type.
9
+ # [Data Types - Spark 3.5.1 Documentation](https://spark.apache.org/docs/latest/sql-ref-datatypes.html)
10
+ RUBY_TO_SPARK_TYPES = {
11
+ binary: 'binary',
12
+ boolean: 'boolean',
13
+ date: 'date',
14
+ datetime: 'timestamp',
15
+ decimal: 'decimal',
16
+ float: 'float',
17
+ integer: 'integer',
18
+ json: 'string',
19
+ string: 'string',
20
+ text: 'string',
21
+ time: 'string'
22
+ }.freeze
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Dbt
5
+ module DataType
6
+ module DwhPlatform
7
+ module Bigquery
8
+ # [Data types  |  BigQuery  |  Google Cloud](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#data_type_list)
9
+ RUBY_TO_BIGQUERY_TYPES = {
10
+ binary: 'bytes',
11
+ boolean: 'bool',
12
+ date: 'date',
13
+ datetime: 'datetime',
14
+ decimal: 'int64',
15
+ float: 'float64',
16
+ integer: 'int64',
17
+ json: 'json',
18
+ string: 'string',
19
+ text: 'string',
20
+ time: 'time'
21
+ }.freeze
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Dbt
5
+ module DataType
6
+ module DwhPlatform
7
+ module PostgreSql
8
+ # TODO: I have not tried it. I don't know if this is the correct data_type.
9
+ # [PostgreSQL: Documentation: 16: Chapter 8. Data Types](https://www.postgresql.org/docs/current/datatype.html)
10
+ RUBY_TO_POSTGRES_TYPES = {
11
+ binary: 'bytea',
12
+ boolean: 'boolean',
13
+ date: 'date',
14
+ datetime: 'timestamp',
15
+ decimal: 'bigint',
16
+ float: 'double precision',
17
+ integer: 'bigint',
18
+ json: 'json',
19
+ string: 'text',
20
+ text: 'text',
21
+ time: 'time'
22
+ }.freeze
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Dbt
5
+ module DataType
6
+ module DwhPlatform
7
+ module Redshift
8
+ # TODO: I have not tried it. I don't know if this is the correct data_type.
9
+ # [Data types - Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/dg/c_Supported_data_types.html)
10
+ RUBY_TO_REDSHIFT_TYPES = {
11
+ binary: 'varbyte',
12
+ boolean: 'bool',
13
+ date: 'date',
14
+ datetime: 'timestamp',
15
+ decimal: 'decimal',
16
+ float: 'double precision',
17
+ integer: 'integer',
18
+ json: 'super',
19
+ string: 'varchar',
20
+ text: 'varchar',
21
+ time: 'time'
22
+ }.freeze
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Dbt
5
+ module DataType
6
+ module DwhPlatform
7
+ module Snowflake
8
+ # TODO: I have not tried it. I don't know if this is the correct data_type.
9
+ # [Summary of data types | Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/intro-summary-data-types)
10
+ RUBY_TO_SNOWFLAKE_TYPES = {
11
+ binary: 'binary',
12
+ boolean: 'boolean',
13
+ date: 'date',
14
+ datetime: 'datetime',
15
+ decimal: 'decimal',
16
+ float: 'float',
17
+ integer: 'integer',
18
+ json: 'variant',
19
+ string: 'varchar',
20
+ text: 'varchar',
21
+ time: 'time'
22
+ }.freeze
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Dbt
5
+ module DataType
6
+ module Mapper
7
+ include ActiveRecord::Dbt::DataType::DwhPlatform::ApacheSpark
8
+ include ActiveRecord::Dbt::DataType::DwhPlatform::Bigquery
9
+ include ActiveRecord::Dbt::DataType::DwhPlatform::PostgreSql
10
+ include ActiveRecord::Dbt::DataType::DwhPlatform::Redshift
11
+ include ActiveRecord::Dbt::DataType::DwhPlatform::Snowflake
12
+
13
+ extend ActiveRecord::Dbt::RequiredMethods
14
+
15
+ # [Platform-specific data types | dbt Developer Hub](https://docs.getdbt.com/reference/resource-properties/data-types)
16
+ RUBY_TO_DWH_PLATFORM_TYPE_MAP = {
17
+ 'bigquery' => RUBY_TO_BIGQUERY_TYPES,
18
+ 'postgres' => RUBY_TO_POSTGRES_TYPES,
19
+ 'redshift' => RUBY_TO_REDSHIFT_TYPES,
20
+ 'snowflake' => RUBY_TO_SNOWFLAKE_TYPES,
21
+ 'spark' => RUBY_TO_SPARK_TYPES
22
+ }.freeze
23
+
24
+ define_required_methods :column, :@config
25
+
26
+ delegate :dwh_platform, to: :@config
27
+
28
+ private
29
+
30
+ def data_type
31
+ RUBY_TO_DWH_PLATFORM_TYPE_MAP[dwh_platform].fetch(column.type, 'unknown')
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -7,32 +7,39 @@ module ActiveRecord
7
7
  module Table
8
8
  module Testable
9
9
  module UniqueCombinationOfColumnsTestable
10
- REQUIRED_UNIQUE_COMBINATION_OF_COLUMNS_TESTABLE_METHODS = %i[table_name @config].freeze
10
+ extend ActiveRecord::Dbt::RequiredMethods
11
11
 
12
- delegate :used_dbt_utils?, to: :@config
12
+ define_required_methods :table_name, :@config
13
13
 
14
- REQUIRED_UNIQUE_COMBINATION_OF_COLUMNS_TESTABLE_METHODS.each do |method_name|
15
- define_method(method_name) do
16
- raise NotImplementedError, "You must implement #{self.class}##{__method__}"
17
- end
18
- end
14
+ delegate :used_dbt_utils?, to: :@config
19
15
 
20
16
  def unique_combination_of_columns_test
21
17
  return nil unless used_dbt_utils?
22
18
 
23
- ActiveRecord::Base.connection.indexes(table_name).each_with_object([]) do |index, array|
24
- next if index.unique == false
25
- next if (unique_indexes = index.columns).size == 1
19
+ indexes.each_with_object([]) do |index, array|
20
+ next if unique_indexes?(index)
26
21
 
27
22
  array.push(
28
23
  {
29
24
  'dbt_utils.unique_combination_of_columns' => {
30
- 'combination_of_columns' => unique_indexes
25
+ 'combination_of_columns' => index.columns
31
26
  }
32
27
  }
33
28
  )
34
29
  end.presence
35
30
  end
31
+
32
+ private
33
+
34
+ def indexes
35
+ ActiveRecord::Base.connection.indexes(table_name)
36
+ end
37
+
38
+ def unique_indexes?(index)
39
+ return true if index.unique == false
40
+
41
+ index.columns.size == 1
42
+ end
36
43
  end
37
44
  end
38
45
  end
@@ -7,33 +7,21 @@ module ActiveRecord
7
7
  module Column
8
8
  module Testable
9
9
  module RelationshipsMetaRelationshipType
10
- REQUIRED_RELATIONSHIP_TYPE_TESTABLE_METHODS = %i[@config foreign_key].freeze
10
+ extend ActiveRecord::Dbt::RequiredMethods
11
11
 
12
- delegate :used_dbterd?, :add_log, to: :@config
12
+ define_required_methods :@config, :foreign_key
13
13
 
14
- REQUIRED_RELATIONSHIP_TYPE_TESTABLE_METHODS.each do |method_name|
15
- define_method(method_name) do
16
- raise NotImplementedError, "You must implement #{self.class}##{__method__}"
17
- end
18
- end
14
+ delegate :used_dbterd?, :add_log, to: :@config
19
15
 
20
16
  def relationships_meta_relationship_type
21
17
  return nil unless used_dbterd?
22
- return nil if foreign_key.nil? || relationship_type.blank?
18
+ return nil if no_relationship?
23
19
 
24
20
  {
25
21
  'relationship_type' => relationship_type
26
22
  }
27
23
  rescue NotSpecifiedOrNotInvalidIdError, StandardError => e
28
- add_log(self.class, e)
29
-
30
- {
31
- 'relationship_type' => 'many-to-one',
32
- 'active_record_dbt_error' => {
33
- 'class' => e.class.to_s,
34
- 'message' => e.message.to_s
35
- }
36
- }
24
+ relationships_meta_relationship_type_with_active_record_dbt_error(e)
37
25
  end
38
26
 
39
27
  private
@@ -128,6 +116,22 @@ module ActiveRecord
128
116
  @to_model ||= foreign_key.to_table.classify.constantize
129
117
  end
130
118
 
119
+ def no_relationship?
120
+ foreign_key.nil? || relationship_type.blank?
121
+ end
122
+
123
+ def relationships_meta_relationship_type_with_active_record_dbt_error(error)
124
+ add_log(self.class, error)
125
+
126
+ {
127
+ 'relationship_type' => 'many-to-one',
128
+ 'active_record_dbt_error' => {
129
+ 'class' => error.class.to_s,
130
+ 'message' => error.message.to_s
131
+ }
132
+ }
133
+ end
134
+
131
135
  class NotSpecifiedOrNotInvalidIdError < StandardError; end
132
136
  end
133
137
  end
@@ -43,19 +43,19 @@ module ActiveRecord
43
43
  def sort_columns(columns)
44
44
  columns.sort_by do |column|
45
45
  [
46
- SORT_COLUMN_TYPES.index(column_type(column)) || -1,
46
+ SORT_COLUMN_TYPES.index(data_type(column)) || -1,
47
47
  columns.index(column)
48
48
  ]
49
49
  end
50
50
  end
51
51
 
52
- def column_type(column)
52
+ def data_type(column)
53
53
  if id?(column['name'])
54
54
  'ids'
55
55
  elsif enum?(column['name'])
56
56
  'enums'
57
57
  else
58
- column.dig('meta', 'column_type').pluralize
58
+ column.fetch('data_type', 'unknown').pluralize
59
59
  end
60
60
  end
61
61
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Dbt
5
+ module RequiredMethods
6
+ def define_required_methods(*methods)
7
+ methods.each do |method_name|
8
+ define_method(method_name) do
9
+ raise RequiredImplementationMissingError, "You must implement #{self.class}##{__method__}"
10
+ end
11
+ end
12
+ end
13
+
14
+ class RequiredImplementationMissingError < StandardError; end
15
+ end
16
+ end
17
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Dbt
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
@@ -11,7 +11,5 @@ module ActiveRecord
11
11
 
12
12
  config
13
13
  end
14
-
15
- class Error < StandardError; end
16
14
  end
17
15
  end
@@ -5,6 +5,7 @@ require 'active_record/dbt'
5
5
  ActiveRecord::Dbt.configure do |c|
6
6
  c.config_directory_path = 'lib/dbt'
7
7
  c.export_directory_path = 'doc/dbt'
8
+ c.dwh_platform = 'bigquery'
8
9
  c.data_sync_delayed = false
9
10
  c.used_dbt_package_names = []
10
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-dbt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yamotech
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-20 00:00:00.000000000 Z
11
+ date: 2024-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -72,9 +72,16 @@ files:
72
72
  - lib/active_record/dbt/column/testable/unique_testable.rb
73
73
  - lib/active_record/dbt/config.rb
74
74
  - lib/active_record/dbt/configuration/data_sync.rb
75
+ - lib/active_record/dbt/configuration/dwh_platform.rb
75
76
  - lib/active_record/dbt/configuration/logger.rb
76
77
  - lib/active_record/dbt/configuration/parser.rb
77
78
  - lib/active_record/dbt/configuration/used_dbt_package.rb
79
+ - lib/active_record/dbt/data_type/dwh_platform/apache_spark.rb
80
+ - lib/active_record/dbt/data_type/dwh_platform/bigquery.rb
81
+ - lib/active_record/dbt/data_type/dwh_platform/postgre_sql.rb
82
+ - lib/active_record/dbt/data_type/dwh_platform/redshift.rb
83
+ - lib/active_record/dbt/data_type/dwh_platform/snowflake.rb
84
+ - lib/active_record/dbt/data_type/mapper.rb
78
85
  - lib/active_record/dbt/dbt_package/dbt_utils/table/testable/unique_combination_of_columns_testable.rb
79
86
  - lib/active_record/dbt/dbt_package/dbterd/column/testable/relationships_meta_relationship_type.rb
80
87
  - lib/active_record/dbt/factory/columns_factory.rb
@@ -86,6 +93,7 @@ files:
86
93
  - lib/active_record/dbt/model/staging/sql.rb
87
94
  - lib/active_record/dbt/model/staging/yml.rb
88
95
  - lib/active_record/dbt/railtie.rb
96
+ - lib/active_record/dbt/required_methods.rb
89
97
  - lib/active_record/dbt/source/yml.rb
90
98
  - lib/active_record/dbt/table/base.rb
91
99
  - lib/active_record/dbt/table/test.rb