Skip to content

Commit 0c20abe

Browse files
committed
integrated SetColumnType into migrations
1 parent 9dbf582 commit 0c20abe

File tree

7 files changed

+75
-10
lines changed

7 files changed

+75
-10
lines changed

piccolo/apps/migrations/auto/diffable_table.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ def __sub__(self, value: DiffableTable) -> TableDelta:
110110
column_name=column._meta.name,
111111
params=deserialise_params(delta),
112112
old_params=old_params,
113+
column_class=column.__class__,
114+
old_column_class=existing_column.__class__,
113115
)
114116
)
115117

piccolo/apps/migrations/auto/migration_manager.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22
from dataclasses import dataclass, field
33
import inspect
4+
from piccolo.query.methods import alter
45
import typing as t
56

67
from piccolo.columns import Column, column_types
@@ -252,6 +253,8 @@ def alter_column(
252253
column_name: str,
253254
params: t.Dict[str, t.Any],
254255
old_params: t.Dict[str, t.Any],
256+
column_class: t.Optional[t.Type[Column]] = None,
257+
old_column_class: t.Optional[t.Type[Column]] = None,
255258
):
256259
"""
257260
All possible alterations aren't currently supported.
@@ -263,6 +266,8 @@ def alter_column(
263266
column_name=column_name,
264267
params=params,
265268
old_params=old_params,
269+
column_class=column_class,
270+
old_column_class=old_column_class,
266271
)
267272
)
268273

@@ -328,9 +333,34 @@ async def _run_alter_columns(self, backwards=False):
328333
_Table: t.Type[Table] = type(table_class_name, (Table,), {})
329334
_Table._meta.tablename = alter_columns[0].tablename
330335

331-
for column in alter_columns:
332-
params = column.old_params if backwards else column.params
333-
column_name = column.column_name
336+
for alter_column in alter_columns:
337+
params = (
338+
alter_column.old_params
339+
if backwards
340+
else alter_column.params
341+
)
342+
column_name = alter_column.column_name
343+
344+
# Change the column type if possible
345+
column_class = alter_column.column_class
346+
old_column_class = alter_column.old_column_class
347+
if (old_column_class is not None) and (
348+
column_class is not None
349+
):
350+
if old_column_class != column_class:
351+
old_column = old_column_class(
352+
**alter_column.old_params
353+
)
354+
old_column._meta._table = _Table
355+
old_column._meta._name = alter_column.column_name
356+
357+
new_column = column_class(**alter_column.params)
358+
new_column._meta._table = _Table
359+
new_column._meta._name = alter_column.column_name
360+
361+
await _Table.alter().set_column_type(
362+
old_column=old_column, new_column=new_column
363+
)
334364

335365
null = params.get("null")
336366
if null is not None:
@@ -383,7 +413,7 @@ async def _run_alter_columns(self, backwards=False):
383413
digits = params.get("digits", ...)
384414
if digits is not ...:
385415
await _Table.alter().set_digits(
386-
column=column.column_name, digits=digits,
416+
column=alter_column.column_name, digits=digits,
387417
).run()
388418

389419
async def _run_drop_tables(self, backwards=False):

piccolo/apps/migrations/auto/operations.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class AlterColumn:
2626
tablename: str
2727
params: t.Dict[str, t.Any]
2828
old_params: t.Dict[str, t.Any]
29+
column_class: t.Optional[t.Type[Column]] = None
30+
old_column_class: t.Optional[t.Type[Column]] = None
2931

3032

3133
@dataclass

piccolo/apps/migrations/auto/schema_differ.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,17 +308,45 @@ def alter_columns(self) -> AlterStatements:
308308
else:
309309
continue
310310

311-
for i in delta.alter_columns:
312-
new_params = serialise_params(i.params)
311+
for alter_column in delta.alter_columns:
312+
new_params = serialise_params(alter_column.params)
313313
extra_imports.extend(new_params.extra_imports)
314314
extra_definitions.extend(new_params.extra_definitions)
315315

316-
old_params = serialise_params(i.old_params)
316+
old_params = serialise_params(alter_column.old_params)
317317
extra_imports.extend(old_params.extra_imports)
318318
extra_definitions.extend(old_params.extra_definitions)
319319

320+
column_class = (
321+
alter_column.column_class.__name__
322+
if alter_column.column_class
323+
else "None"
324+
)
325+
326+
old_column_class = (
327+
alter_column.old_column_class.__name__
328+
if alter_column.old_column_class
329+
else "None"
330+
)
331+
332+
if alter_column.column_class is not None:
333+
extra_imports.append(
334+
Import(
335+
module=alter_column.column_class.__module__,
336+
target=alter_column.column_class.__name__,
337+
)
338+
)
339+
340+
if alter_column.old_column_class is not None:
341+
extra_imports.append(
342+
Import(
343+
module=alter_column.old_column_class.__module__,
344+
target=alter_column.old_column_class.__name__,
345+
)
346+
)
347+
320348
response.append(
321-
f"manager.alter_column(table_class_name='{table.class_name}', tablename='{table.tablename}', column_name='{i.column_name}', params={new_params.params}, old_params={old_params.params})" # noqa: E501
349+
f"manager.alter_column(table_class_name='{table.class_name}', tablename='{table.tablename}', column_name='{alter_column.column_name}', params={new_params.params}, old_params={old_params.params}, column_class={column_class}, old_column_class={old_column_class})" # noqa: E501
322350
)
323351

324352
return AlterStatements(

piccolo/query/methods/alter.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ class SetColumnType(AlterStatement):
100100

101101
@property
102102
def querystring(self) -> QueryString:
103-
self.new_column._meta._table = self.old_column._meta.table
103+
if self.new_column._meta._table is None:
104+
self.new_column._meta._table = self.old_column._meta.table
105+
104106
column_name = self.old_column._meta.name
105107
return QueryString(
106108
f"ALTER COLUMN {column_name} TYPE {self.new_column.column_type}"

tests/apps/migrations/auto/test_schema_differ.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def test_alter_column_precision(self):
187187
self.assertTrue(len(schema_differ.alter_columns.statements) == 1)
188188
self.assertEqual(
189189
schema_differ.alter_columns.statements[0],
190-
"manager.alter_column(table_class_name='Ticket', tablename='ticket', column_name='price', params={'digits': (4, 2)}, old_params={'digits': (5, 2)})", # noqa
190+
"manager.alter_column(table_class_name='Ticket', tablename='ticket', column_name='price', params={'digits': (4, 2)}, old_params={'digits': (5, 2)}, column_class=Numeric, old_column_class=Numeric)", # noqa
191191
)
192192

193193
def test_alter_default(self):

tests/table/test_alter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ def test_multiple(self):
137137
self.assertTrue("column_b" in column_names)
138138

139139

140+
# TODO - test more conversions.
140141
@postgres_only
141142
class TestSetColumnType(DBTestCase):
142143
def test_integer_to_bigint(self):

0 commit comments

Comments
 (0)