Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decouple adapter constraints from core #9054

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/dbt/adapters/base/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from multiprocessing.context import SpawnContext

from dbt.adapters.capability import Capability, CapabilityDict
from dbt.contracts.graph.nodes import ColumnLevelConstraint, ConstraintType, ModelLevelConstraint
from dbt.common.constraints import ColumnLevelConstraint, ConstraintType, ModelLevelConstraint

import agate
import pytz
Expand Down
43 changes: 43 additions & 0 deletions core/dbt/common/constraints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from dataclasses import dataclass, field
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we consider constraints a 'contract'? If so we should move it to common/contracts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MichelleArk What do you think about this?

Copy link
Contributor

@MichelleArk MichelleArk Nov 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree - common/contracts makes sense as a home for these based on the existing patterns we have in dbt & dbt/adapters. I'm thinking common/contracts/constraints.py

from enum import Enum
from typing import Optional, List

from dbt.common.dataclass_schema import dbtClassMixin


class ConstraintType(str, Enum):
check = "check"
not_null = "not_null"
unique = "unique"
primary_key = "primary_key"
foreign_key = "foreign_key"
custom = "custom"

@classmethod
def is_valid(cls, item) -> bool:
try:
cls(item)
except ValueError:
return False
return True

Check warning on line 22 in core/dbt/common/constraints.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/common/constraints.py#L22

Added line #L22 was not covered by tests


@dataclass
class ColumnLevelConstraint(dbtClassMixin):
type: ConstraintType
name: Optional[str] = None
# expression is a user-provided field that will depend on the constraint type.
# It could be a predicate (check type), or a sequence sql keywords (e.g. unique type),
# so the vague naming of 'expression' is intended to capture this range.
expression: Optional[str] = None
warn_unenforced: bool = (
True # Warn if constraint cannot be enforced by platform but will be in DDL
)
warn_unsupported: bool = (
True # Warn if constraint is not supported by the platform and won't be in DDL
)


@dataclass
class ModelLevelConstraint(ColumnLevelConstraint):
columns: List[str] = field(default_factory=list)
40 changes: 1 addition & 39 deletions core/dbt/contracts/graph/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
from datetime import datetime
import time
from dataclasses import dataclass, field
from enum import Enum
import hashlib

from mashumaro.types import SerializableType
from typing import Optional, Union, List, Dict, Any, Sequence, Tuple, Iterator, Literal

from dbt.common.constraints import ColumnLevelConstraint, ConstraintType, ModelLevelConstraint
from dbt.common.dataclass_schema import dbtClassMixin, ExtensibleDbtClassMixin

from dbt.clients.system import write_file
Expand Down Expand Up @@ -178,44 +178,6 @@ def keyword_args(self) -> Dict[str, Optional[NodeVersion]]:
return {}


class ConstraintType(str, Enum):
check = "check"
not_null = "not_null"
unique = "unique"
primary_key = "primary_key"
foreign_key = "foreign_key"
custom = "custom"

@classmethod
def is_valid(cls, item):
try:
cls(item)
except ValueError:
return False
return True


@dataclass
class ColumnLevelConstraint(dbtClassMixin):
type: ConstraintType
name: Optional[str] = None
# expression is a user-provided field that will depend on the constraint type.
# It could be a predicate (check type), or a sequence sql keywords (e.g. unique type),
# so the vague naming of 'expression' is intended to capture this range.
expression: Optional[str] = None
warn_unenforced: bool = (
True # Warn if constraint cannot be enforced by platform but will be in DDL
)
warn_unsupported: bool = (
True # Warn if constraint is not supported by the platform and won't be in DDL
)


@dataclass
class ModelLevelConstraint(ColumnLevelConstraint):
columns: List[str] = field(default_factory=list)


@dataclass
class ColumnInfo(AdditionalPropertiesMixin, ExtensibleDbtClassMixin, Replaceable):
"""Used in all ManifestNodes and SourceDefinition"""
Expand Down
8 changes: 2 additions & 6 deletions core/dbt/parser/common.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from dbt.common.constraints import ColumnLevelConstraint, ConstraintType
from dbt.contracts.graph.unparsed import (
HasColumnProps,
UnparsedColumn,
Expand All @@ -8,12 +9,7 @@
UnparsedModelUpdate,
)
from dbt.contracts.graph.unparsed import NodeVersion, HasColumnTests, HasColumnDocs
from dbt.contracts.graph.nodes import (
UnpatchedSourceDefinition,
ColumnInfo,
ColumnLevelConstraint,
ConstraintType,
)
from dbt.contracts.graph.nodes import UnpatchedSourceDefinition, ColumnInfo
from dbt.parser.search import FileBlock
from typing import List, Dict, Any, TypeVar, Generic, Union, Optional
from dataclasses import dataclass
Expand Down
3 changes: 1 addition & 2 deletions core/dbt/parser/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Any, Callable, Dict, Generic, Iterable, List, Optional, Type, TypeVar
from dataclasses import dataclass, field

from dbt.common.constraints import ConstraintType, ModelLevelConstraint
from dbt.common.dataclass_schema import ValidationError, dbtClassMixin

from dbt.clients.yaml_helper import load_yaml_text
Expand All @@ -17,9 +18,7 @@
ParsedNodePatch,
ParsedMacroPatch,
UnpatchedSourceDefinition,
ConstraintType,
ModelNode,
ModelLevelConstraint,
)
from dbt.contracts.graph.unparsed import (
HasColumnDocs,
Expand Down
2 changes: 1 addition & 1 deletion plugins/postgres/dbt/adapters/postgres/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
from dbt.adapters.postgres import PostgresConnectionManager
from dbt.adapters.postgres.column import PostgresColumn
from dbt.adapters.postgres import PostgresRelation
from dbt.common.constraints import ConstraintType
from dbt.common.dataclass_schema import dbtClassMixin, ValidationError
from dbt.common.exceptions import DbtRuntimeError
from dbt.contracts.graph.nodes import ConstraintType
from dbt.adapters.exceptions import (
CrossDbReferenceProhibitedError,
IndexConfigNotDictError,
Expand Down
Loading