django-migrate-sql-deux 0.4.0__tar.gz → 0.5.2__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 (63) hide show
  1. django_migrate_sql_deux-0.5.2/LICENSE +13 -0
  2. django_migrate_sql_deux-0.5.2/PKG-INFO +302 -0
  3. django_migrate_sql_deux-0.5.2/django_migrate_sql_deux.egg-info/PKG-INFO +302 -0
  4. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/django_migrate_sql_deux.egg-info/SOURCES.txt +2 -0
  5. django_migrate_sql_deux-0.5.2/migrate_sql/__init__.py +1 -0
  6. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/migrate_sql/management/commands/makemigrations.py +2 -1
  7. django_migrate_sql_deux-0.5.2/pyproject.toml +25 -0
  8. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/setup.py +0 -1
  9. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_project/settings.py +1 -0
  10. django-migrate-sql-deux-0.4.0/PKG-INFO +0 -295
  11. django-migrate-sql-deux-0.4.0/django_migrate_sql_deux.egg-info/PKG-INFO +0 -295
  12. django-migrate-sql-deux-0.4.0/migrate_sql/__init__.py +0 -1
  13. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/README.rst +0 -0
  14. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/django_migrate_sql_deux.egg-info/dependency_links.txt +0 -0
  15. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/django_migrate_sql_deux.egg-info/not-zip-safe +0 -0
  16. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/django_migrate_sql_deux.egg-info/top_level.txt +0 -0
  17. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/migrate_sql/autodetector.py +0 -0
  18. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/migrate_sql/config.py +0 -0
  19. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/migrate_sql/graph.py +0 -0
  20. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/migrate_sql/management/__init__.py +0 -0
  21. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/migrate_sql/management/commands/__init__.py +0 -0
  22. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/migrate_sql/operations.py +0 -0
  23. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/setup.cfg +0 -0
  24. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/__init__.py +0 -0
  25. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/manage.py +0 -0
  26. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/__init__.py +0 -0
  27. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/apps.py +0 -0
  28. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations/0001_initial.py +0 -0
  29. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations/__init__.py +0 -0
  30. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_change/0001_initial.py +0 -0
  31. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_change/0002_auto_20151224_1827.py +0 -0
  32. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_change/__init__.py +0 -0
  33. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_deps_delete/0001_initial.py +0 -0
  34. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_deps_delete/0002_auto_20160106_0947.py +0 -0
  35. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_deps_delete/0003_auto_20160108_0048.py +0 -0
  36. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_deps_delete/0004_auto_20160108_0048.py +0 -0
  37. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_deps_delete/__init__.py +0 -0
  38. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_deps_update/0001_initial.py +0 -0
  39. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_deps_update/0002_auto_20160106_0947.py +0 -0
  40. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_deps_update/__init__.py +0 -0
  41. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_recreate/0001_initial.py +0 -0
  42. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_recreate/0002_auto_20151224_1827.py +0 -0
  43. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_recreate/0003_auto_20160106_1038.py +0 -0
  44. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/migrations_recreate/__init__.py +0 -0
  45. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/models.py +0 -0
  46. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/sql_config.py +0 -0
  47. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/test_migrations.py +0 -0
  48. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/test_utils.py +0 -0
  49. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app/urls.py +0 -0
  50. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/__init__.py +0 -0
  51. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/apps.py +0 -0
  52. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/migrations/__init__.py +0 -0
  53. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/migrations_deps_delete/0001_initial.py +0 -0
  54. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/migrations_deps_delete/0002_auto_20160108_0041.py +0 -0
  55. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/migrations_deps_delete/__init__.py +0 -0
  56. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/migrations_deps_update/0001_initial.py +0 -0
  57. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/migrations_deps_update/__init__.py +0 -0
  58. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/models.py +0 -0
  59. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/sql_config.py +0 -0
  60. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_app2/urls.py +0 -0
  61. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_project/__init__.py +0 -0
  62. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_project/urls.py +0 -0
  63. {django-migrate-sql-deux-0.4.0 → django_migrate_sql_deux-0.5.2}/tests/test_project/wsgi.py +0 -0
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2016, Bogdan Klichuk <klichukb@gmail.com>
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,302 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-migrate-sql-deux
3
+ Version: 0.5.2
4
+ Summary: Migration support for raw SQL in Django
5
+ Home-page: https://github.com/festicket/django-migrate-sql
6
+ Author: Festicket
7
+ Author-email: dev@festicket.com
8
+ License: BSD
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Framework :: Django
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Natural Language :: English
14
+ Classifier: Programming Language :: Python :: 3.6
15
+ Classifier: Programming Language :: Python :: 3.7
16
+ Classifier: Framework :: Django :: 2.1
17
+ Classifier: Framework :: Django :: 2.2
18
+ Classifier: Framework :: Django :: 3.0
19
+ License-File: LICENSE
20
+ Dynamic: author
21
+ Dynamic: author-email
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: home-page
25
+ Dynamic: license
26
+ Dynamic: license-file
27
+ Dynamic: summary
28
+
29
+ django-migrate-sql-deux
30
+ =======================
31
+
32
+ .. note::
33
+
34
+ This package is a fork of the ``django-migrate-sql`` package, originally published
35
+ by Bogdan Klichuk. This package appears unmaintained, so we decided to start a fork
36
+ as we depended on it. Most of the code is from him.
37
+
38
+ |Build Status| |codecov.io|
39
+
40
+ Django Migrations support for raw SQL.
41
+
42
+ About
43
+ -----
44
+
45
+ This tool implements mechanism for managing changes to custom SQL
46
+ entities (functions, types, indices, triggers) using built-in migration
47
+ mechanism. Technically creates a sophistication layer on top of the
48
+ ``RunSQL`` Django operation.
49
+
50
+ What it does
51
+ ------------
52
+
53
+ - Makes maintaining your SQL functions, custom composite types, indices
54
+ and triggers easier.
55
+ - Structures SQL into configuration of **SQL items**, that are
56
+ identified by names and divided among apps, just like models.
57
+ - Automatically gathers and persists changes of your custom SQL into
58
+ migrations using ``makemigrations``.
59
+ - Properly executes backwards/forwards keeping integrity of database.
60
+ - Create -> Drop -> Recreate approach for changes to items that do not
61
+ support altering and require dropping and recreating.
62
+ - Dependencies system for SQL items, which solves the problem of
63
+ updating items, that rely on others (for example custom
64
+ types/functions that use other custom types), and require dropping
65
+ all dependency tree previously with further recreation.
66
+
67
+ What it does not
68
+ ----------------
69
+
70
+ - Does not parse SQL nor validate queries during ``makemigrations`` or
71
+ ``migrate`` because is database-agnostic. For this same reason
72
+ setting up proper dependencies is user's responsibility.
73
+ - Does not create ``ALTER`` queries for items that support this, for
74
+ example ``ALTER TYPE`` in Postgre SQL, because is database-agnostic.
75
+ In case your tools allow rolling all the changes through ``ALTER``
76
+ queries, you can consider not using this app **or** restructure
77
+ migrations manually after creation by nesting generated operations
78
+ into ```state_operations`` of
79
+ ``RunSQL`` <https://docs.djangoproject.com/en/1.8/ref/migration-operations/#runsql>`__
80
+ that does ``ALTER``.
81
+ - (**TODO**)During ``migrate`` does not restore full state of items for
82
+ analysis, thus does not notify about existing changes to schema that
83
+ are not migrated **nor** does not recognize circular dependencies
84
+ during migration execution.
85
+
86
+ Installation
87
+ ------------
88
+
89
+ Install from PyPi:
90
+
91
+ ::
92
+
93
+ $ pip install django-migrate-sql-deux
94
+
95
+ Add ``migrate_sql`` to ``INSTALLED_APPS``:
96
+
97
+ .. code:: python
98
+
99
+ INSTALLED_APPS = [
100
+ # ...
101
+ 'migrate_sql',
102
+ ]
103
+
104
+ App defines a custom ``makemigrations`` command, that inherits from
105
+ Django's core one, so in order ``migrate_sql`` app to kick in put it
106
+ after any other apps that redefine ``makemigrations`` command too.
107
+
108
+ Usage
109
+ -----
110
+
111
+ 1) Create ``sql_config.py`` module to root of a target app you want to
112
+ manage custom SQL for.
113
+
114
+ 2) Define SQL items in it (``sql_items``), for example:
115
+
116
+ .. code:: python
117
+
118
+ # PostgreSQL example.
119
+ # Let's define a simple function and let `migrate_sql` manage it's changes.
120
+
121
+ from migrate_sql.config import SQLItem
122
+
123
+ sql_items = [
124
+ SQLItem(
125
+ 'make_sum', # name of the item
126
+ 'create or replace function make_sum(a int, b int) returns int as $$ '
127
+ 'begin return a + b; end; '
128
+ '$$ language plpgsql;', # forward sql
129
+ reverse_sql='drop function make_sum(int, int);', # sql for removal
130
+ ),
131
+ ]
132
+
133
+ 3) Create migration ``./manage.py makemigrations``:
134
+
135
+ ::
136
+
137
+ Migrations for 'app_name':
138
+ 0002_auto_xxxx.py:
139
+ - Create SQL "make_sum"
140
+
141
+ You can take a look at content this generated:
142
+
143
+ .. code:: python
144
+
145
+ # -*- coding: utf-8 -*-
146
+ from __future__ import unicode_literals
147
+ from django.db import migrations, models
148
+ import migrate_sql.operations
149
+
150
+
151
+ class Migration(migrations.Migration):
152
+ dependencies = [
153
+ ('app_name', '0001_initial'),
154
+ ]
155
+ operations = [
156
+ migrate_sql.operations.CreateSQL(
157
+ name='make_sum',
158
+ sql='create or replace function make_sum(a int, b int) returns int as $$ begin return a + b; end; $$ language plpgsql;',
159
+ reverse_sql='drop function make_sum(int, int);',
160
+ ),
161
+ ]
162
+
163
+ 4) Execute migration ``./manage.py migrate``:
164
+
165
+ ::
166
+
167
+ Operations to perform:
168
+ Apply all migrations: app_name
169
+ Running migrations:
170
+ Rendering model states... DONE
171
+ Applying app_name.0002_xxxx... OK
172
+
173
+ Check result in ``./manage.py dbshell``:
174
+
175
+ ::
176
+
177
+ db_name=# select make_sum(12, 15);
178
+ make_sum
179
+ ----------
180
+ 27
181
+ (1 row)
182
+
183
+ Now, say, you want to change the function implementation so that it
184
+ takes a custom type as argument:
185
+
186
+ 5) Edit your ``sql_config.py``:
187
+
188
+ .. code:: python
189
+
190
+ # PostgreSQL example #2.
191
+ # Function and custom type.
192
+
193
+ from migrate_sql.config import SQLItem
194
+
195
+ sql_items = [
196
+ SQLItem(
197
+ 'make_sum', # name of the item
198
+ 'create or replace function make_sum(a mynum, b mynum) returns mynum as $$ '
199
+ 'begin return (a.num + b.num, 'result')::mynum; end; '
200
+ '$$ language plpgsql;', # forward sql
201
+ reverse_sql='drop function make_sum(mynum, mynum);', # sql for removal
202
+ # depends on `mynum` since takes it as argument. we won't be able to drop function
203
+ # without dropping `mynum` first.
204
+ dependencies=[('app_name', 'mynum')],
205
+ ),
206
+ SQLItem(
207
+ 'mynum' # name of the item
208
+ 'create type mynum as (num int, name varchar(20));', # forward sql
209
+ reverse_sql='drop type mynum;', # sql for removal
210
+ ),
211
+ ]
212
+
213
+ 6) Generate migration ``./manage.py makemigrations``:
214
+
215
+ ::
216
+
217
+ Migrations for 'app_name':
218
+ 0003_xxxx:
219
+ - Reverse alter SQL "make_sum"
220
+ - Create SQL "mynum"
221
+ - Alter SQL "make_sum"
222
+ - Alter SQL state "make_sum"
223
+
224
+ You can take a look at the content this generated:
225
+
226
+ .. code:: python
227
+
228
+ # -*- coding: utf-8 -*-
229
+ from __future__ import unicode_literals
230
+ from django.db import migrations, models
231
+ import migrate_sql.operations
232
+
233
+
234
+ class Migration(migrations.Migration):
235
+ dependencies = [
236
+ ('app_name', '0002_xxxx'),
237
+ ]
238
+ operations = [
239
+ migrate_sql.operations.ReverseAlterSQL(
240
+ name='make_sum',
241
+ sql='drop function make_sum(int, int);',
242
+ reverse_sql='create or replace function make_sum(a int, b int) returns int as $$ begin return a + b; end; $$ language plpgsql;',
243
+ ),
244
+ migrate_sql.operations.CreateSQL(
245
+ name='mynum',
246
+ sql='create type mynum as (num int, name varchar(20));',
247
+ reverse_sql='drop type mynum;',
248
+ ),
249
+ migrate_sql.operations.AlterSQL(
250
+ name='make_sum',
251
+ sql='create or replace function make_sum(a mynum, b mynum) returns mynum as $$ begin return (a.num + b.num, \'result\')::mynum; end; $$ language plpgsql;',
252
+ reverse_sql='drop function make_sum(mynum, mynum);',
253
+ ),
254
+ migrate_sql.operations.AlterSQLState(
255
+ name='make_sum',
256
+ add_dependencies=(('app_name', 'mynum'),),
257
+ ),
258
+ ]
259
+
260
+ ***NOTE:** Previous function is completely dropped before creation
261
+ because definition of it changed. ``CREATE OR REPLACE`` would create
262
+ another version of it, so ``DROP`` makes it clean.*
263
+
264
+ ***If you put ``replace=True`` as kwarg to an ``SQLItem`` definition, it
265
+ will NOT drop + create it, but just rerun forward SQL, which is
266
+ ``CREATE OR REPLACE`` in this example.***
267
+
268
+ 7) Execute migration ``./manage.py migrate``:
269
+
270
+ ::
271
+
272
+ Operations to perform:
273
+ Apply all migrations: app_name
274
+ Running migrations:
275
+ Rendering model states... DONE
276
+ Applying brands.0003_xxxx... OK
277
+
278
+ Check results:
279
+
280
+ ::
281
+
282
+ db_name=# select make_sum((5, 'a')::mynum, (3, 'b')::mynum);
283
+ make_sum
284
+ ------------
285
+ (8,result)
286
+ (1 row)
287
+
288
+ db_name=# select make_sum(12, 15);
289
+ ERROR: function make_sum(integer, integer) does not exist
290
+ LINE 1: select make_sum(12, 15);
291
+ ^
292
+ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
293
+
294
+ For more examples see ``tests``.
295
+
296
+ Feel free to `open new
297
+ issues <https://github.com/klichukb/django-migrate-sql/issues>`__.
298
+
299
+ .. |Build Status| image:: https://travis-ci.org/klichukb/django-migrate-sql.svg?branch=master
300
+ :target: https://travis-ci.org/klichukb/django-migrate-sql
301
+ .. |codecov.io| image:: https://img.shields.io/codecov/c/github/klichukb/django-migrate-sql/master.svg
302
+ :target: https://codecov.io/github/klichukb/django-migrate-sql?branch=master
@@ -0,0 +1,302 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-migrate-sql-deux
3
+ Version: 0.5.2
4
+ Summary: Migration support for raw SQL in Django
5
+ Home-page: https://github.com/festicket/django-migrate-sql
6
+ Author: Festicket
7
+ Author-email: dev@festicket.com
8
+ License: BSD
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Framework :: Django
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Natural Language :: English
14
+ Classifier: Programming Language :: Python :: 3.6
15
+ Classifier: Programming Language :: Python :: 3.7
16
+ Classifier: Framework :: Django :: 2.1
17
+ Classifier: Framework :: Django :: 2.2
18
+ Classifier: Framework :: Django :: 3.0
19
+ License-File: LICENSE
20
+ Dynamic: author
21
+ Dynamic: author-email
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: home-page
25
+ Dynamic: license
26
+ Dynamic: license-file
27
+ Dynamic: summary
28
+
29
+ django-migrate-sql-deux
30
+ =======================
31
+
32
+ .. note::
33
+
34
+ This package is a fork of the ``django-migrate-sql`` package, originally published
35
+ by Bogdan Klichuk. This package appears unmaintained, so we decided to start a fork
36
+ as we depended on it. Most of the code is from him.
37
+
38
+ |Build Status| |codecov.io|
39
+
40
+ Django Migrations support for raw SQL.
41
+
42
+ About
43
+ -----
44
+
45
+ This tool implements mechanism for managing changes to custom SQL
46
+ entities (functions, types, indices, triggers) using built-in migration
47
+ mechanism. Technically creates a sophistication layer on top of the
48
+ ``RunSQL`` Django operation.
49
+
50
+ What it does
51
+ ------------
52
+
53
+ - Makes maintaining your SQL functions, custom composite types, indices
54
+ and triggers easier.
55
+ - Structures SQL into configuration of **SQL items**, that are
56
+ identified by names and divided among apps, just like models.
57
+ - Automatically gathers and persists changes of your custom SQL into
58
+ migrations using ``makemigrations``.
59
+ - Properly executes backwards/forwards keeping integrity of database.
60
+ - Create -> Drop -> Recreate approach for changes to items that do not
61
+ support altering and require dropping and recreating.
62
+ - Dependencies system for SQL items, which solves the problem of
63
+ updating items, that rely on others (for example custom
64
+ types/functions that use other custom types), and require dropping
65
+ all dependency tree previously with further recreation.
66
+
67
+ What it does not
68
+ ----------------
69
+
70
+ - Does not parse SQL nor validate queries during ``makemigrations`` or
71
+ ``migrate`` because is database-agnostic. For this same reason
72
+ setting up proper dependencies is user's responsibility.
73
+ - Does not create ``ALTER`` queries for items that support this, for
74
+ example ``ALTER TYPE`` in Postgre SQL, because is database-agnostic.
75
+ In case your tools allow rolling all the changes through ``ALTER``
76
+ queries, you can consider not using this app **or** restructure
77
+ migrations manually after creation by nesting generated operations
78
+ into ```state_operations`` of
79
+ ``RunSQL`` <https://docs.djangoproject.com/en/1.8/ref/migration-operations/#runsql>`__
80
+ that does ``ALTER``.
81
+ - (**TODO**)During ``migrate`` does not restore full state of items for
82
+ analysis, thus does not notify about existing changes to schema that
83
+ are not migrated **nor** does not recognize circular dependencies
84
+ during migration execution.
85
+
86
+ Installation
87
+ ------------
88
+
89
+ Install from PyPi:
90
+
91
+ ::
92
+
93
+ $ pip install django-migrate-sql-deux
94
+
95
+ Add ``migrate_sql`` to ``INSTALLED_APPS``:
96
+
97
+ .. code:: python
98
+
99
+ INSTALLED_APPS = [
100
+ # ...
101
+ 'migrate_sql',
102
+ ]
103
+
104
+ App defines a custom ``makemigrations`` command, that inherits from
105
+ Django's core one, so in order ``migrate_sql`` app to kick in put it
106
+ after any other apps that redefine ``makemigrations`` command too.
107
+
108
+ Usage
109
+ -----
110
+
111
+ 1) Create ``sql_config.py`` module to root of a target app you want to
112
+ manage custom SQL for.
113
+
114
+ 2) Define SQL items in it (``sql_items``), for example:
115
+
116
+ .. code:: python
117
+
118
+ # PostgreSQL example.
119
+ # Let's define a simple function and let `migrate_sql` manage it's changes.
120
+
121
+ from migrate_sql.config import SQLItem
122
+
123
+ sql_items = [
124
+ SQLItem(
125
+ 'make_sum', # name of the item
126
+ 'create or replace function make_sum(a int, b int) returns int as $$ '
127
+ 'begin return a + b; end; '
128
+ '$$ language plpgsql;', # forward sql
129
+ reverse_sql='drop function make_sum(int, int);', # sql for removal
130
+ ),
131
+ ]
132
+
133
+ 3) Create migration ``./manage.py makemigrations``:
134
+
135
+ ::
136
+
137
+ Migrations for 'app_name':
138
+ 0002_auto_xxxx.py:
139
+ - Create SQL "make_sum"
140
+
141
+ You can take a look at content this generated:
142
+
143
+ .. code:: python
144
+
145
+ # -*- coding: utf-8 -*-
146
+ from __future__ import unicode_literals
147
+ from django.db import migrations, models
148
+ import migrate_sql.operations
149
+
150
+
151
+ class Migration(migrations.Migration):
152
+ dependencies = [
153
+ ('app_name', '0001_initial'),
154
+ ]
155
+ operations = [
156
+ migrate_sql.operations.CreateSQL(
157
+ name='make_sum',
158
+ sql='create or replace function make_sum(a int, b int) returns int as $$ begin return a + b; end; $$ language plpgsql;',
159
+ reverse_sql='drop function make_sum(int, int);',
160
+ ),
161
+ ]
162
+
163
+ 4) Execute migration ``./manage.py migrate``:
164
+
165
+ ::
166
+
167
+ Operations to perform:
168
+ Apply all migrations: app_name
169
+ Running migrations:
170
+ Rendering model states... DONE
171
+ Applying app_name.0002_xxxx... OK
172
+
173
+ Check result in ``./manage.py dbshell``:
174
+
175
+ ::
176
+
177
+ db_name=# select make_sum(12, 15);
178
+ make_sum
179
+ ----------
180
+ 27
181
+ (1 row)
182
+
183
+ Now, say, you want to change the function implementation so that it
184
+ takes a custom type as argument:
185
+
186
+ 5) Edit your ``sql_config.py``:
187
+
188
+ .. code:: python
189
+
190
+ # PostgreSQL example #2.
191
+ # Function and custom type.
192
+
193
+ from migrate_sql.config import SQLItem
194
+
195
+ sql_items = [
196
+ SQLItem(
197
+ 'make_sum', # name of the item
198
+ 'create or replace function make_sum(a mynum, b mynum) returns mynum as $$ '
199
+ 'begin return (a.num + b.num, 'result')::mynum; end; '
200
+ '$$ language plpgsql;', # forward sql
201
+ reverse_sql='drop function make_sum(mynum, mynum);', # sql for removal
202
+ # depends on `mynum` since takes it as argument. we won't be able to drop function
203
+ # without dropping `mynum` first.
204
+ dependencies=[('app_name', 'mynum')],
205
+ ),
206
+ SQLItem(
207
+ 'mynum' # name of the item
208
+ 'create type mynum as (num int, name varchar(20));', # forward sql
209
+ reverse_sql='drop type mynum;', # sql for removal
210
+ ),
211
+ ]
212
+
213
+ 6) Generate migration ``./manage.py makemigrations``:
214
+
215
+ ::
216
+
217
+ Migrations for 'app_name':
218
+ 0003_xxxx:
219
+ - Reverse alter SQL "make_sum"
220
+ - Create SQL "mynum"
221
+ - Alter SQL "make_sum"
222
+ - Alter SQL state "make_sum"
223
+
224
+ You can take a look at the content this generated:
225
+
226
+ .. code:: python
227
+
228
+ # -*- coding: utf-8 -*-
229
+ from __future__ import unicode_literals
230
+ from django.db import migrations, models
231
+ import migrate_sql.operations
232
+
233
+
234
+ class Migration(migrations.Migration):
235
+ dependencies = [
236
+ ('app_name', '0002_xxxx'),
237
+ ]
238
+ operations = [
239
+ migrate_sql.operations.ReverseAlterSQL(
240
+ name='make_sum',
241
+ sql='drop function make_sum(int, int);',
242
+ reverse_sql='create or replace function make_sum(a int, b int) returns int as $$ begin return a + b; end; $$ language plpgsql;',
243
+ ),
244
+ migrate_sql.operations.CreateSQL(
245
+ name='mynum',
246
+ sql='create type mynum as (num int, name varchar(20));',
247
+ reverse_sql='drop type mynum;',
248
+ ),
249
+ migrate_sql.operations.AlterSQL(
250
+ name='make_sum',
251
+ sql='create or replace function make_sum(a mynum, b mynum) returns mynum as $$ begin return (a.num + b.num, \'result\')::mynum; end; $$ language plpgsql;',
252
+ reverse_sql='drop function make_sum(mynum, mynum);',
253
+ ),
254
+ migrate_sql.operations.AlterSQLState(
255
+ name='make_sum',
256
+ add_dependencies=(('app_name', 'mynum'),),
257
+ ),
258
+ ]
259
+
260
+ ***NOTE:** Previous function is completely dropped before creation
261
+ because definition of it changed. ``CREATE OR REPLACE`` would create
262
+ another version of it, so ``DROP`` makes it clean.*
263
+
264
+ ***If you put ``replace=True`` as kwarg to an ``SQLItem`` definition, it
265
+ will NOT drop + create it, but just rerun forward SQL, which is
266
+ ``CREATE OR REPLACE`` in this example.***
267
+
268
+ 7) Execute migration ``./manage.py migrate``:
269
+
270
+ ::
271
+
272
+ Operations to perform:
273
+ Apply all migrations: app_name
274
+ Running migrations:
275
+ Rendering model states... DONE
276
+ Applying brands.0003_xxxx... OK
277
+
278
+ Check results:
279
+
280
+ ::
281
+
282
+ db_name=# select make_sum((5, 'a')::mynum, (3, 'b')::mynum);
283
+ make_sum
284
+ ------------
285
+ (8,result)
286
+ (1 row)
287
+
288
+ db_name=# select make_sum(12, 15);
289
+ ERROR: function make_sum(integer, integer) does not exist
290
+ LINE 1: select make_sum(12, 15);
291
+ ^
292
+ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
293
+
294
+ For more examples see ``tests``.
295
+
296
+ Feel free to `open new
297
+ issues <https://github.com/klichukb/django-migrate-sql/issues>`__.
298
+
299
+ .. |Build Status| image:: https://travis-ci.org/klichukb/django-migrate-sql.svg?branch=master
300
+ :target: https://travis-ci.org/klichukb/django-migrate-sql
301
+ .. |codecov.io| image:: https://img.shields.io/codecov/c/github/klichukb/django-migrate-sql/master.svg
302
+ :target: https://codecov.io/github/klichukb/django-migrate-sql?branch=master
@@ -1,4 +1,6 @@
1
+ LICENSE
1
2
  README.rst
3
+ pyproject.toml
2
4
  setup.cfg
3
5
  setup.py
4
6
  django_migrate_sql_deux.egg-info/PKG-INFO
@@ -0,0 +1 @@
1
+ __version__ = '0.5.2'
@@ -8,7 +8,7 @@ import sys
8
8
  from django.core.management.commands.makemigrations import Command as MakeMigrationsCommand
9
9
  from django.db.migrations.loader import MigrationLoader
10
10
  from django.db.migrations import Migration
11
- from django.core.management.base import CommandError
11
+ from django.core.management.base import CommandError, no_translations
12
12
  from django.db.migrations.questioner import InteractiveMigrationQuestioner
13
13
  from django.apps import apps
14
14
  from django.db.migrations.state import ProjectState
@@ -19,6 +19,7 @@ from migrate_sql.graph import build_current_graph
19
19
 
20
20
  class Command(MakeMigrationsCommand):
21
21
 
22
+ @no_translations
22
23
  def handle(self, *app_labels, **options):
23
24
 
24
25
  self.verbosity = options.get('verbosity')
@@ -0,0 +1,25 @@
1
+ [tool.semantic_release]
2
+ tag_format = "v{version}"
3
+ version_variables = [ "migrate_sql/__init__.py:__version__" ]
4
+ build_command = """
5
+ pip install build
6
+ python -m build
7
+ """
8
+
9
+ [tool.semantic_release.changelog]
10
+ mode = "update"
11
+ exclude_commit_patterns = [
12
+ "chore.*",
13
+ "ci.*",
14
+ "Merge pull request .*",
15
+ ]
16
+
17
+ [tool.semantic_release.changelog.environment]
18
+ keep_trailing_newline = true
19
+
20
+ [tool.semantic_release.branches.main]
21
+ match = "main"
22
+
23
+ [tool.semantic_release.branches.noop]
24
+ match = "(?!main$)"
25
+ prerelease = true
@@ -64,7 +64,6 @@ setup(
64
64
  'Natural Language :: English',
65
65
  'Programming Language :: Python :: 3.6',
66
66
  'Programming Language :: Python :: 3.7',
67
- 'Framework :: Django :: 2.0',
68
67
  'Framework :: Django :: 2.1',
69
68
  'Framework :: Django :: 2.2',
70
69
  'Framework :: Django :: 3.0',
@@ -78,6 +78,7 @@ DATABASES = {
78
78
  'ENGINE': 'django.db.backends.postgresql_psycopg2',
79
79
  'NAME': 'migrate_sql_test_db',
80
80
  'USER': 'postgres',
81
+ 'PASSWORD': 'postgres',
81
82
  'HOST': 'localhost',
82
83
  'PORT': 5432,
83
84
  }