diff options
| author | cheremnov <32135863+cheremnov@users.noreply.github.com> | 2022-02-24 02:22:33 -0500 |
|---|---|---|
| committer | Federico Caselli <cfederico87@gmail.com> | 2022-06-29 09:13:37 +0000 |
| commit | 5fb63bc1423e75812a24e809d16731a3282c2a12 (patch) | |
| tree | 2e3293890e1b326146ea8848ceac9a65fae9490b /lib/sqlalchemy/engine | |
| parent | 6a560cf03c302d2ebd9ae7c7dc4d587983096ba4 (diff) | |
| download | sqlalchemy-5fb63bc1423e75812a24e809d16731a3282c2a12.tar.gz | |
Comments on (named) constraints
Adds support for comments on named constraints, including `ForeignKeyConstraint`, `PrimaryKeyConstraint`, `CheckConstraint`, `UniqueConstraint`, solving the [Issue 5667](https://github.com/sqlalchemy/sqlalchemy/issues/5667).
Supports only PostgreSQL backend.
### Description
Following the example of [Issue 1546](https://github.com/sqlalchemy/sqlalchemy/issues/1546), supports comments on constraints. Specifically, enables comments on _named_ ones — as I get it, PostgreSQL prohibits comments on unnamed constraints.
Enables setting the comments for named constraints like this:
```
Table(
'example', metadata,
Column('id', Integer),
Column('data', sa.String(30)),
PrimaryKeyConstraint(
"id", name="id_pk", comment="id_pk comment"
),
CheckConstraint('id < 100', name="cc1", comment="Id value can't exceed 100"),
UniqueConstraint(['data'], name="uc1", comment="Must have unique data field"),
)
```
Provides the DDL representation for constraint comments and routines to create and drop them. Class `.Inspector` reflects constraint comments via methods like `get_check_constraints` .
### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)
-->
This pull request is:
- [ ] A documentation / typographical error fix
- [ ] A short code fix
- [x] A new feature implementation
- Solves the issue 5667.
- The commit message includes `Fixes: 5667`.
- Includes tests based on comment reflection.
**Have a nice day!**
Fixes: #5667
Closes: #7742
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/7742
Pull-request-sha: 42a5d3c3e9ccf9a9d5397fd007aeab0854f66130
Change-Id: Ia60f578595afdbd6089541c9a00e37997ef78ad3
Diffstat (limited to 'lib/sqlalchemy/engine')
| -rw-r--r-- | lib/sqlalchemy/engine/default.py | 1 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/interfaces.py | 40 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/reflection.py | 21 |
3 files changed, 44 insertions, 18 deletions
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 40af06252..5d3ff8bb7 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -113,6 +113,7 @@ class DefaultDialect(Dialect): preparer = compiler.IdentifierPreparer supports_alter = True supports_comments = False + supports_constraint_comments = False inline_comments = False supports_statement_cache = True diff --git a/lib/sqlalchemy/engine/interfaces.py b/lib/sqlalchemy/engine/interfaces.py index 28ed03f99..c33666e4b 100644 --- a/lib/sqlalchemy/engine/interfaces.py +++ b/lib/sqlalchemy/engine/interfaces.py @@ -357,7 +357,21 @@ class ReflectedColumn(TypedDict): object""" -class ReflectedCheckConstraint(TypedDict): +class ReflectedConstraint(TypedDict): + """Dictionary representing the reflected elements corresponding to + :class:`.Constraint` + + A base class for all constraints + """ + + name: Optional[str] + """constraint name""" + + comment: NotRequired[Optional[str]] + """comment for the constraint, if present""" + + +class ReflectedCheckConstraint(ReflectedConstraint): """Dictionary representing the reflected elements corresponding to :class:`.CheckConstraint`. @@ -366,9 +380,6 @@ class ReflectedCheckConstraint(TypedDict): """ - name: Optional[str] - """constraint name""" - sqltext: str """the check constraint's SQL expression""" @@ -377,7 +388,7 @@ class ReflectedCheckConstraint(TypedDict): object""" -class ReflectedUniqueConstraint(TypedDict): +class ReflectedUniqueConstraint(ReflectedConstraint): """Dictionary representing the reflected elements corresponding to :class:`.UniqueConstraint`. @@ -386,9 +397,6 @@ class ReflectedUniqueConstraint(TypedDict): """ - name: Optional[str] - """constraint name""" - column_names: List[str] """column names which comprise the constraint""" @@ -400,7 +408,7 @@ class ReflectedUniqueConstraint(TypedDict): object""" -class ReflectedPrimaryKeyConstraint(TypedDict): +class ReflectedPrimaryKeyConstraint(ReflectedConstraint): """Dictionary representing the reflected elements corresponding to :class:`.PrimaryKeyConstraint`. @@ -409,9 +417,6 @@ class ReflectedPrimaryKeyConstraint(TypedDict): """ - name: Optional[str] - """constraint name""" - constrained_columns: List[str] """column names which comprise the constraint""" @@ -420,7 +425,7 @@ class ReflectedPrimaryKeyConstraint(TypedDict): object""" -class ReflectedForeignKeyConstraint(TypedDict): +class ReflectedForeignKeyConstraint(ReflectedConstraint): """Dictionary representing the reflected elements corresponding to :class:`.ForeignKeyConstraint`. @@ -429,9 +434,6 @@ class ReflectedForeignKeyConstraint(TypedDict): """ - name: Optional[str] - """constraint name""" - constrained_columns: List[str] """local column names which comprise the constraint""" @@ -888,6 +890,12 @@ class Dialect(EventTarget): definition of a Table or Column. If False, this implies that ALTER must be used to set table and column comments.""" + supports_constraint_comments: bool + """Indicates if the dialect supports comment DDL on constraints. + + .. versionadded: 2.0 + """ + _has_events = False supports_statement_cache: bool = True diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index 655a9f5c1..9bac97db0 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -974,6 +974,9 @@ class Inspector(inspection.Inspectable["Inspector"]): * ``name`` - optional name of the primary key constraint. + * ``comment`` - + optional comment on the primary key constraint. + :param table_name: string name of the table. For special quoting, use :class:`.quoted_name`. @@ -1073,6 +1076,9 @@ class Inspector(inspection.Inspectable["Inspector"]): * ``name`` - optional name of the foreign key constraint. + * ``comment`` - + optional comment on the foreign key constraint + :param table_name: string name of the table. For special quoting, use :class:`.quoted_name`. @@ -1273,6 +1279,9 @@ class Inspector(inspection.Inspectable["Inspector"]): * ``column_names`` - list of column names in order + * ``comment`` - + optional comment on the constraint + :param table_name: string name of the table. For special quoting, use :class:`.quoted_name`. @@ -1462,6 +1471,9 @@ class Inspector(inspection.Inspectable["Inspector"]): may or may not be present; a dictionary with additional dialect-specific options for this CHECK constraint + * ``comment`` - + optional comment on the constraint + .. versionadded:: 1.3.8 :param table_name: string name of the table. For special quoting, @@ -1785,8 +1797,9 @@ class Inspector(inspection.Inspectable["Inspector"]): if pk in cols_by_orig_name and pk not in exclude_columns ] - # update pk constraint name + # update pk constraint name and comment table.primary_key.name = pk_cons.get("name") + table.primary_key.comment = pk_cons.get("comment", None) # tell the PKConstraint to re-initialize # its column collection @@ -1867,6 +1880,7 @@ class Inspector(inspection.Inspectable["Inspector"]): refspec, conname, link_to_name=True, + comment=fkey_d.get("comment"), **options, ) ) @@ -1948,6 +1962,7 @@ class Inspector(inspection.Inspectable["Inspector"]): for const_d in constraints: conname = const_d["name"] columns = const_d["column_names"] + comment = const_d.get("comment") duplicates = const_d.get("duplicates_index") if include_columns and not set(columns).issubset(include_columns): continue @@ -1971,7 +1986,9 @@ class Inspector(inspection.Inspectable["Inspector"]): else: constrained_cols.append(constrained_col) table.append_constraint( - sa_schema.UniqueConstraint(*constrained_cols, name=conname) + sa_schema.UniqueConstraint( + *constrained_cols, name=conname, comment=comment + ) ) def _reflect_check_constraints( |
