-
-
Notifications
You must be signed in to change notification settings - Fork 246
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
Preserve comment and info in Drop/CreateTableOp #881
Preserve comment and info in Drop/CreateTableOp #881
Conversation
hello there - thanks for this! has a test and everything. I am on vacation this week so have limited time to check into things. will run this through CI. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision 6ed4ed0 of this pull request into gerrit so we can run tests and reviews and stuff
New Gerrit review created for change 6ed4ed0: https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
hi and thanks for doing this!
changes we need include:
-
a changelog file docs/build/unreleased/879.rst needs to be added
-
we do need some factoring as you mention to make DropTableOp look like CreateTableOp but I think it should be for now that CreateTableOp->**kw and DropTableOp->table_kw are treated equivalently for now, no new arguments added
-
for pep8/flake8, black formatting needs to be run on the files. Best way to do this is to use pre-commit:
$ cd /path/to/alembic
$ pre-commit install
the correct formatting steps will take place when you next commit. do a "git commit --amend" and force-push the PR to make sure it gets all the files that were changed.
im on vacation this week so i may not respond quickly.
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989
-
/COMMIT_MSG (line 24): that's public API and while I can see DropTable is different, that's because the arguments sent to Table are currently only used during CREATE TABLE; I believe table_kw was added to better support "reversal" of the DropTableOp back into CreateTableOp. would not change any of that within this change.
-
/COMMIT_MSG (line 36): this definition of "==" is still relevant; if you want a comparison of two Table objects based on their contents, use the .compare() method, 1.4 and above:
from sqlalchemy import Table, MetaData
t1 = Table('name', MetaData(schema='plop'))
t2 = Table('name', MetaData(schema='plop'))
t1.compare(t2)
True
t3 = Table('notname', MetaData(schema='plop'))
t1.compare(t3)
False -
/COMMIT_MSG (line 62): please add:
Fixes:
Drop/CreateTableOp.from_table()
no longer copy the table'sSchemaItem.info
#879
alembic/operations/ops.py
Outdated
@@ -959,6 +959,7 @@ def __init__( | |||
self.comment = kw.pop("comment", None) | |||
self.prefixes = kw.pop("prefixes", None) | |||
self.kw = kw | |||
self.table_info = kw.pop('info', {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
call this ".info"
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989
alembic/operations/ops.py
Outdated
def __init__(self, | ||
table_name, | ||
schema=None, | ||
table_comment=None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
I think these both need to come from table_kw using the "pop" form. if we were to refactor this further, "table_kw" would become "**kw" just like CreateTableOp.
Also we need to add "prefixes" here.
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989
alembic/operations/ops.py
Outdated
self.table_kw = table_kw or {} | ||
self.table_info = table_info or {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
implement as:
self.info = table_kw.pop("info", None)
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989
op = ops.DropTableOp.from_table(table) | ||
is_not_(op.to_table(), table) | ||
eq_(op.to_table().comment, table.comment) | ||
eq_(op.to_table().info, table.info) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
see if we can add "prefixes"
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989
op = ops.CreateTableOp.from_table(table) | ||
is_not_(op.to_table(), table) | ||
eq_(op.to_table().comment, table.comment) | ||
eq_(op.to_table().info, table.info) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
see if we can add "prefixes"
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989
a022835
to
9f711a0
Compare
alembic/operations/ops.py
Outdated
table_kw=table.kwargs, | ||
comment=table.comment, | ||
info=table.info, | ||
prefixes=table._prefixes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is a list and is hence mutable. shouldn't we copy it ? Same for info, which is a dict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is a good idea, seems to not be critical but then i may not be envisioning how these structures may be used, so sure.
9f711a0
to
300e862
Compare
table_kw={ | ||
"comment": table.comment, | ||
"info": table.info, | ||
"prefixes": table._prefixes, | ||
**table.kwargs, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only way I can see to not break the class' __init__()
public API.
I cannot help but wonder how much of public API this is though. Indeed, even when reverting a CreateTableOp
, for example, DropTableOp.from_table()
is used (see l. 967). But on principle I agree, we should not break it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are on the edge of a new "minor" series 0.7 so it's a better time to change the API but I felt for the moment it's best to make this PR work without changing any public API, then make public API changes between these two objects something separate.
300e862
to
257b987
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision 257b987 of this pull request into gerrit so we can run tests and reviews and stuff
Patchset 257b987 added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989 |
257b987
to
f01d5f4
Compare
The `DropTableOp.from_table()` method loses the table's `SchemaItem.info` and `comment` attributes while the `CreateTableOp` only loses the `info` attribute. This commit fixes both issues. Fixes sqlalchemy#879.
f01d5f4
to
e509b9e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision e509b9e of this pull request into gerrit so we can run tests and reviews and stuff
Patchset e509b9e added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989 |
specifically, i want to look at the |
mike bayer (zzzeek) wrote: this looks good to me as is, im going to add a changelog file and also revert that formatting change for now, if we want to work with the kw API to make it make more sense we can approach that separately. View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/2989 |
also #849 was a similar issue |
oh i guess black has made those formatting changes, OK. |
i will also dict-/list- ify info and prefixes. |
not sure why there where not there already |
Just added the copy of diff --git a/alembic/operations/ops.py b/alembic/operations/ops.py
index 5d04a8e..31da81d 100644
--- a/alembic/operations/ops.py
+++ b/alembic/operations/ops.py
@@ -1,3 +1,4 @@
+import copy
import re
from sqlalchemy.types import NULLTYPE
@@ -956,9 +957,9 @@ class CreateTableOp(MigrateOperation):
self.table_name = table_name
self.columns = columns
self.schema = schema
- self.info = kw.pop("info", {})
self.comment = kw.pop("comment", None)
- self.prefixes = kw.pop("prefixes", None)
+ self.info = copy.deepcopy(kw.pop("info", None))
+ self.prefixes = copy.copy(kw.pop("prefixes", None))
self.kw = kw
self._namespace_metadata = _namespace_metadata
self._constraints_included = _constraints_included
@@ -1099,8 +1100,8 @@ class DropTableOp(MigrateOperation):
self.schema = schema
self.table_kw = table_kw or {}
self.comment = self.table_kw.pop("comment", None)
- self.info = self.table_kw.pop("info", None)
- self.prefixes = self.table_kw.pop("prefixes", None)
+ self.info = copy.deepcopy(self.table_kw.pop("info", None))
+ self.prefixes = copy.copy(self.table_kw.pop("prefixes", None))
self._reverse = _reverse
def to_diff_tuple(self): |
I guess I won't... couldn't push to github. |
yeah i wouldnt use deepcopy() here. this is pushed. thanks! |
This is a fix for issue #879
Description
The
DropTableOp.from_table()
method loses the table'sSchemaItem.info
andcomment
attributes while theCreateTableOp.from_table()
only loses theinfo
attribute.This means the following assertion does not hold, when a table goes through a from_table() to_table() round trip:
This commit fixes both issues.
Notes:
While fixing this I found the implementations of the Create/DropTableOp to be strangely assymetrical, in particular wrt. the way each deals with extra keywords one can pass to a table. Happy to refactor this a little if you'd like me to.
There is table equality notion implemented. But it seems reliant on the identity of the tables
MetaData
though, which kind of makes sense if you want to be 100% it is the same object, in the exact same database (given the DB URI+schema name+table name, etc.).Given that the
MetaData
object is going "bind-free" in SQLAlchemy 2.0, I wonder if this definition of table equality is still relevant, though.Checklist
This pull request is:
must include a complete example of the issue. one line code fixes without an
issue and demonstration will not be accepted.
Fixes: #<issue number>
in the commit messageinclude a complete example of how the feature would look.
Fixes: #<issue number>
in the commit messageHave a nice day!
Thanks, you too !