django-migrate-sql-deux 1.2.0__tar.gz → 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/PKG-INFO +15 -7
  2. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/README.md +14 -6
  3. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/pyproject.toml +1 -1
  4. django_migrate_sql_deux-1.3.0/src/django_migrate_sql/__init__.py +1 -0
  5. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql/config.py +29 -2
  6. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql_deux.egg-info/PKG-INFO +15 -7
  7. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql_deux.egg-info/SOURCES.txt +1 -0
  8. django_migrate_sql_deux-1.3.0/tests/test_config.py +187 -0
  9. django_migrate_sql_deux-1.2.0/src/django_migrate_sql/__init__.py +0 -1
  10. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/LICENSE +0 -0
  11. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/setup.cfg +0 -0
  12. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql/autodetector.py +0 -0
  13. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql/graph.py +0 -0
  14. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql/management/__init__.py +0 -0
  15. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql/management/commands/__init__.py +0 -0
  16. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql/management/commands/makemigrations.py +0 -0
  17. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql/management/commands/migrate.py +0 -0
  18. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql/operations.py +0 -0
  19. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql_deux.egg-info/dependency_links.txt +0 -0
  20. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql_deux.egg-info/requires.txt +0 -0
  21. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/src/django_migrate_sql_deux.egg-info/top_level.txt +0 -0
  22. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/tests/test_migrate_command.py +0 -0
  23. {django_migrate_sql_deux-1.2.0 → django_migrate_sql_deux-1.3.0}/tests/test_system_checks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-migrate-sql-deux
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Django Migrations for raw SQL
5
5
  Author-email: Bogdan Klichuk <klichukb@gmail.com>, Bruno Alla <oss@browniebroke.com>
6
6
  License-Expression: ISC
@@ -181,9 +181,13 @@ Note that
181
181
  sql_items = [
182
182
  SQLItem(
183
183
  'make_sum', # name of the item
184
- 'create or replace function make_sum(a int, b int) returns int as $$ '
185
- 'begin return a + b; end; '
186
- '$$ language plpgsql;', # forward sql
184
+ """
185
+ create or replace function make_sum(a int, b int) returns int as $$
186
+ begin
187
+ return a + b;
188
+ end;
189
+ $$ language plpgsql;
190
+ """, # forward sql
187
191
  reverse_sql='drop function make_sum(int, int);', # sql for removal
188
192
  ),
189
193
  ]
@@ -252,9 +256,13 @@ Now, say, you want to change the function implementation so that it takes a cust
252
256
  sql_items = [
253
257
  SQLItem(
254
258
  "make_sum", # name of the item
255
- "create or replace function make_sum(a mynum, b mynum) returns mynum as $$ "
256
- "begin return (a.num + b.num, 'result')::mynum; end;"
257
- "$$ language plpgsql;", # forward sql
259
+ """
260
+ create or replace function make_sum(a mynum, b mynum) returns mynum as $$
261
+ begin
262
+ return (a.num + b.num, 'result')::mynum;
263
+ end;
264
+ $$ language plpgsql;
265
+ """, # forward sql
258
266
  reverse_sql="drop function make_sum(mynum, mynum);", # sql for removal
259
267
  # depends on `mynum` since takes it as argument. we won't be able to drop function
260
268
  # without dropping `mynum` first.
@@ -151,9 +151,13 @@ Note that
151
151
  sql_items = [
152
152
  SQLItem(
153
153
  'make_sum', # name of the item
154
- 'create or replace function make_sum(a int, b int) returns int as $$ '
155
- 'begin return a + b; end; '
156
- '$$ language plpgsql;', # forward sql
154
+ """
155
+ create or replace function make_sum(a int, b int) returns int as $$
156
+ begin
157
+ return a + b;
158
+ end;
159
+ $$ language plpgsql;
160
+ """, # forward sql
157
161
  reverse_sql='drop function make_sum(int, int);', # sql for removal
158
162
  ),
159
163
  ]
@@ -222,9 +226,13 @@ Now, say, you want to change the function implementation so that it takes a cust
222
226
  sql_items = [
223
227
  SQLItem(
224
228
  "make_sum", # name of the item
225
- "create or replace function make_sum(a mynum, b mynum) returns mynum as $$ "
226
- "begin return (a.num + b.num, 'result')::mynum; end;"
227
- "$$ language plpgsql;", # forward sql
229
+ """
230
+ create or replace function make_sum(a mynum, b mynum) returns mynum as $$
231
+ begin
232
+ return (a.num + b.num, 'result')::mynum;
233
+ end;
234
+ $$ language plpgsql;
235
+ """, # forward sql
228
236
  reverse_sql="drop function make_sum(mynum, mynum);", # sql for removal
229
237
  # depends on `mynum` since takes it as argument. we won't be able to drop function
230
238
  # without dropping `mynum` first.
@@ -4,7 +4,7 @@ requires = [ "setuptools>=77.0.3" ]
4
4
 
5
5
  [project]
6
6
  name = "django-migrate-sql-deux"
7
- version = "1.2.0"
7
+ version = "1.3.0"
8
8
  description = "Django Migrations for raw SQL"
9
9
  readme = "README.md"
10
10
  license = "ISC"
@@ -0,0 +1 @@
1
+ __version__ = "1.3.0"
@@ -1,3 +1,6 @@
1
+ import textwrap
2
+
3
+
1
4
  class SQLItem:
2
5
  """
3
6
  Represents any SQL entity (unit), for example function, type, index or trigger.
@@ -21,7 +24,31 @@ class SQLItem:
21
24
 
22
25
  """
23
26
  self.name = name
24
- self.sql = sql
25
- self.reverse_sql = reverse_sql
27
+ self.sql = self._process_sql(sql)
28
+ self.reverse_sql = self._process_sql(reverse_sql)
26
29
  self.dependencies = dependencies or []
27
30
  self.replace = replace
31
+
32
+ def _process_sql(self, sql):
33
+ """
34
+ Process SQL by applying textwrap.dedent() to strings.
35
+
36
+ Args:
37
+ sql (str/tuple/list): SQL string or tuple/list of (sql, params).
38
+
39
+ Returns:
40
+ Processed SQL in the same format as input.
41
+
42
+ """
43
+ if isinstance(sql, str):
44
+ return textwrap.dedent(sql)
45
+ if isinstance(sql, (tuple, list)):
46
+ return [
47
+ (textwrap.dedent(item[0]), item[1])
48
+ if isinstance(item, (tuple, list))
49
+ else textwrap.dedent(item)
50
+ if isinstance(item, str)
51
+ else item
52
+ for item in sql
53
+ ]
54
+ return sql
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-migrate-sql-deux
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Django Migrations for raw SQL
5
5
  Author-email: Bogdan Klichuk <klichukb@gmail.com>, Bruno Alla <oss@browniebroke.com>
6
6
  License-Expression: ISC
@@ -181,9 +181,13 @@ Note that
181
181
  sql_items = [
182
182
  SQLItem(
183
183
  'make_sum', # name of the item
184
- 'create or replace function make_sum(a int, b int) returns int as $$ '
185
- 'begin return a + b; end; '
186
- '$$ language plpgsql;', # forward sql
184
+ """
185
+ create or replace function make_sum(a int, b int) returns int as $$
186
+ begin
187
+ return a + b;
188
+ end;
189
+ $$ language plpgsql;
190
+ """, # forward sql
187
191
  reverse_sql='drop function make_sum(int, int);', # sql for removal
188
192
  ),
189
193
  ]
@@ -252,9 +256,13 @@ Now, say, you want to change the function implementation so that it takes a cust
252
256
  sql_items = [
253
257
  SQLItem(
254
258
  "make_sum", # name of the item
255
- "create or replace function make_sum(a mynum, b mynum) returns mynum as $$ "
256
- "begin return (a.num + b.num, 'result')::mynum; end;"
257
- "$$ language plpgsql;", # forward sql
259
+ """
260
+ create or replace function make_sum(a mynum, b mynum) returns mynum as $$
261
+ begin
262
+ return (a.num + b.num, 'result')::mynum;
263
+ end;
264
+ $$ language plpgsql;
265
+ """, # forward sql
258
266
  reverse_sql="drop function make_sum(mynum, mynum);", # sql for removal
259
267
  # depends on `mynum` since takes it as argument. we won't be able to drop function
260
268
  # without dropping `mynum` first.
@@ -15,5 +15,6 @@ src/django_migrate_sql_deux.egg-info/SOURCES.txt
15
15
  src/django_migrate_sql_deux.egg-info/dependency_links.txt
16
16
  src/django_migrate_sql_deux.egg-info/requires.txt
17
17
  src/django_migrate_sql_deux.egg-info/top_level.txt
18
+ tests/test_config.py
18
19
  tests/test_migrate_command.py
19
20
  tests/test_system_checks.py
@@ -0,0 +1,187 @@
1
+ from django_migrate_sql.config import SQLItem
2
+
3
+
4
+ def test_dedent_simple_string():
5
+ """Test that dedent works on a simple indented string."""
6
+ item = SQLItem(
7
+ "test_func",
8
+ """
9
+ CREATE FUNCTION test() RETURNS int AS $$
10
+ BEGIN
11
+ RETURN 1;
12
+ END;
13
+ $$ LANGUAGE plpgsql;
14
+ """,
15
+ reverse_sql="DROP FUNCTION test();",
16
+ )
17
+ # Should remove common leading whitespace
18
+ assert item.sql.startswith("\nCREATE FUNCTION")
19
+ assert " BEGIN" in item.sql
20
+ assert item.reverse_sql == "DROP FUNCTION test();"
21
+
22
+
23
+ def test_dedent_reverse_sql():
24
+ """Test that dedent works on reverse_sql."""
25
+ item = SQLItem(
26
+ "test_func",
27
+ "CREATE FUNCTION test() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql;",
28
+ reverse_sql="""
29
+ DROP FUNCTION test();
30
+ """,
31
+ )
32
+ assert item.reverse_sql.strip() == "DROP FUNCTION test();"
33
+
34
+
35
+ def test_dedent_with_tuple_sql():
36
+ """Test that dedent works with tuple format (sql with parameters)."""
37
+ item = SQLItem(
38
+ "test_func",
39
+ [
40
+ (
41
+ """
42
+ CREATE FUNCTION test(min_val int) RETURNS int AS $$
43
+ BEGIN
44
+ RETURN min_val + %s;
45
+ END;
46
+ $$ LANGUAGE plpgsql;
47
+ """,
48
+ [5],
49
+ )
50
+ ],
51
+ )
52
+ # Should dedent the SQL string in the tuple
53
+ assert isinstance(item.sql, list)
54
+ assert len(item.sql) == 1
55
+ sql_text, params = item.sql[0]
56
+ assert sql_text.startswith("\nCREATE FUNCTION")
57
+ assert params == [5]
58
+
59
+
60
+ def test_dedent_preserves_single_line():
61
+ """Test that single-line SQL strings work correctly."""
62
+ item = SQLItem(
63
+ "test_func",
64
+ "CREATE FUNCTION test() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql;",
65
+ reverse_sql="DROP FUNCTION test();",
66
+ )
67
+ assert item.sql == "CREATE FUNCTION test() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql;"
68
+ assert item.reverse_sql == "DROP FUNCTION test();"
69
+
70
+
71
+ def test_dedent_with_no_indentation():
72
+ """Test that SQL without indentation is not affected."""
73
+ sql = "CREATE FUNCTION test() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql;"
74
+ item = SQLItem("test_func", sql, reverse_sql="DROP FUNCTION test();")
75
+ assert item.sql == sql
76
+
77
+
78
+ def test_dedent_with_dependencies():
79
+ """Test that dedent works with dependencies specified."""
80
+ item = SQLItem(
81
+ "test_func",
82
+ """
83
+ CREATE FUNCTION test() RETURNS mytype AS $$
84
+ BEGIN
85
+ RETURN (1, 'test')::mytype;
86
+ END;
87
+ $$ LANGUAGE plpgsql;
88
+ """,
89
+ reverse_sql="DROP FUNCTION test();",
90
+ dependencies=[("test_app", "mytype")],
91
+ )
92
+ assert item.sql.startswith("\nCREATE FUNCTION")
93
+ assert item.dependencies == [("test_app", "mytype")]
94
+
95
+
96
+ def test_dedent_with_replace_flag():
97
+ """Test that dedent works with replace flag."""
98
+ item = SQLItem(
99
+ "test_func",
100
+ """
101
+ CREATE OR REPLACE FUNCTION test() RETURNS int AS $$
102
+ BEGIN
103
+ RETURN 1;
104
+ END;
105
+ $$ LANGUAGE plpgsql;
106
+ """,
107
+ reverse_sql="DROP FUNCTION test();",
108
+ replace=True,
109
+ )
110
+ assert item.sql.startswith("\nCREATE OR REPLACE FUNCTION")
111
+ assert item.replace is True
112
+
113
+
114
+ def test_dedent_with_list_of_strings():
115
+ """Test that dedent works with a list containing plain strings (not tuples)."""
116
+ item = SQLItem(
117
+ "test_func",
118
+ [
119
+ """
120
+ CREATE FUNCTION test() RETURNS int AS $$
121
+ BEGIN
122
+ RETURN 1;
123
+ END;
124
+ $$ LANGUAGE plpgsql;
125
+ """
126
+ ],
127
+ )
128
+ assert isinstance(item.sql, list)
129
+ assert len(item.sql) == 1
130
+ assert item.sql[0].startswith("\nCREATE FUNCTION")
131
+
132
+
133
+ def test_dedent_with_none_sql():
134
+ """Test that None sql is handled correctly."""
135
+ # This tests the edge case where sql might be None
136
+ # In practice, this shouldn't happen but we test the return sql path
137
+ item = SQLItem(
138
+ "test_func",
139
+ "CREATE FUNCTION test() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql;",
140
+ reverse_sql=None,
141
+ )
142
+ assert item.reverse_sql is None
143
+
144
+ # Test with integer - should be returned unchanged
145
+ item = SQLItem(
146
+ "test_func",
147
+ 123,
148
+ )
149
+ assert item.sql == 123
150
+
151
+
152
+ def test_dedent_with_list_containing_none():
153
+ """Test that None in a list is returned as-is without error."""
154
+ # Test list with None - should be returned unchanged
155
+ item = SQLItem(
156
+ "test_func",
157
+ [None],
158
+ )
159
+ assert isinstance(item.sql, list)
160
+ assert len(item.sql) == 1
161
+ assert item.sql[0] is None
162
+
163
+ # Test mixed list with string, tuple, and None
164
+ item2 = SQLItem(
165
+ "test_func2",
166
+ [
167
+ """
168
+ CREATE FUNCTION test() RETURNS int AS $$
169
+ BEGIN RETURN 1; END;
170
+ $$ LANGUAGE plpgsql;
171
+ """,
172
+ (
173
+ """
174
+ CREATE FUNCTION test2() RETURNS int AS $$
175
+ BEGIN RETURN 2; END;
176
+ $$ LANGUAGE plpgsql;
177
+ """,
178
+ [],
179
+ ),
180
+ None,
181
+ ],
182
+ )
183
+ assert isinstance(item2.sql, list)
184
+ assert len(item2.sql) == 3
185
+ assert item2.sql[0].startswith("\nCREATE FUNCTION test()")
186
+ assert isinstance(item2.sql[1], tuple)
187
+ assert item2.sql[2] is None
@@ -1 +0,0 @@
1
- __version__ = "1.2.0"