-
Notifications
You must be signed in to change notification settings - Fork 6
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
Add support for tables with primary keys not named id
#11
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -4,7 +4,7 @@ | |||||||||||||
import sqlalchemy | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
__version__ = "0.0.4" | ||||||||||||||
__version__ = "0.0.5" | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
def _group_models_by_base_mapper(initial_models): | ||||||||||||||
|
@@ -19,7 +19,7 @@ def _get_column_python_type(column): | |||||||||||||
|
||||||||||||||
|
||||||||||||||
def _has_normal_id_primary_key(base_mapper): | ||||||||||||||
"""Check if the primary key for base_mapper is an auto-incrementing integer `id` column""" | ||||||||||||||
"""Check if the primary key for base_mapper is an auto-incrementing integer column""" | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 - could you generalize the remaining instances of For example, Hoping to generalize all instances of |
||||||||||||||
primary_key_cols = base_mapper.primary_key | ||||||||||||||
if len(primary_key_cols) != 1: | ||||||||||||||
return False | ||||||||||||||
|
@@ -32,16 +32,23 @@ def _has_normal_id_primary_key(base_mapper): | |||||||||||||
python_column_type = None | ||||||||||||||
|
||||||||||||||
return ( | ||||||||||||||
primary_key_col.name == "id" | ||||||||||||||
and python_column_type == int | ||||||||||||||
and primary_key_col.autoincrement in ("auto", True) | ||||||||||||||
and primary_key_col.table == base_mapper.local_table | ||||||||||||||
python_column_type == int | ||||||||||||||
and primary_key_col.autoincrement in ("auto", True) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed an existing issue that For example, in my company's codebase, we have Notably,
Even though this is an existing issue, for that codebase, it started appearing with non-
Open to others! CC: @vineetgopal |
||||||||||||||
and primary_key_col.table == base_mapper.local_table | ||||||||||||||
Comment on lines
+35
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you follow the single-indent style from before?
Suggested change
We should eventually set up a code formatter for this codebase to automate. |
||||||||||||||
) | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
def _get_primary_key_name(base_mapper): | ||||||||||||||
primary_key_cols = base_mapper.primary_key | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed an existing issue that the module assumes the attribute name and column name are the same, but there could be exceptions to that if a caller defines Here's a start, but open to simpler implementations: [primary_key_col_attr] = [c for c in base_mapper.column_attrs if primary_key_col in c.columns]
assert primary_key_col.name == primary_key_col_attr.key, \
"_get_primary_key_name only supports columns whose name equals their attribute name" |
||||||||||||||
[primary_key_col] = primary_key_cols | ||||||||||||||
return primary_key_col.name | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
def _get_id_sequence_name(base_mapper): | ||||||||||||||
assert _has_normal_id_primary_key(base_mapper), "_get_id_sequence_name only supports id primary keys" | ||||||||||||||
return "%s_id_seq" % base_mapper.entity.__tablename__ | ||||||||||||||
assert _has_normal_id_primary_key(base_mapper), \ | ||||||||||||||
"_get_id_sequence_name only supports single auto increment primary keys" | ||||||||||||||
primary_key = _get_primary_key_name(base_mapper) | ||||||||||||||
return f"{base_mapper.entity.__tablename__}_{primary_key}_seq" | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This brought up a good discussion on how backward compatible we should be with Python 2. For this release, our answer is yes, let's remain backward compatible. Accordingly, could you change to the old-style string formatting from before?
Suggested change
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
def tuples_to_scalar_list(tuples): | ||||||||||||||
|
@@ -153,11 +160,13 @@ def batch_populate_primary_keys( | |||||||||||||
if skip_unsupported_models: | ||||||||||||||
continue | ||||||||||||||
else: | ||||||||||||||
raise AssertionError("Expected models to have auto-incrementing `id` primary key") | ||||||||||||||
raise AssertionError("Expected models to have auto-incrementing primary key") | ||||||||||||||
|
||||||||||||||
primary_key = _get_primary_key_name(base_mapper) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you rename to
Suggested change
|
||||||||||||||
|
||||||||||||||
# In general, batch_populate_primary_keys shouldn't assume anything about how people are creating | ||||||||||||||
# models - it is possible for models to have their ids already specified. | ||||||||||||||
models = [model for model in models if model.id is None] | ||||||||||||||
models = [model for model in models if getattr(model, primary_key) is None] | ||||||||||||||
|
||||||||||||||
if skip_if_single_model and len(models) <= 1: | ||||||||||||||
continue | ||||||||||||||
|
@@ -166,7 +175,7 @@ def batch_populate_primary_keys( | |||||||||||||
|
||||||||||||||
models = sorted(models, key=lambda model: sqlalchemy.inspect(model).insert_order) | ||||||||||||||
for id_, model in zip(new_ids, models): | ||||||||||||||
model.id = id_ | ||||||||||||||
setattr(model, primary_key, id_) | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
def enable_batch_inserting(sqla_session): | ||||||||||||||
|
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 brought up a good discussion on if we should separate functional and version changes. Currently our answer is yes, let's separate functional from version changes. That way, we can separately decide how to bump the version.
Accordingly, could you revert this line?
After this merges, I will (1) bump this and setup.py to a new version and (2) release.