Name | django-migrate-sql-3 JSON |
Version |
3.0.2
JSON |
| download |
home_page | None |
Summary | A package parsing the PostgreSQL connection service file |
upload_time | 2024-04-19 09:51:12 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.9 |
license | MIT License |
keywords |
postgres
service
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# django-migrate-sql
This package is a fork of the `django-migrate-sql` package, originally
published by Bogdan Klichuk, later by @festicket. These packages appears unmaintained, so we
decided to start a fork as we depended on it. Most of the code is from
him.
:::
Django Migrations support for raw SQL.
## About
This tool implements mechanism for managing changes to custom SQL
entities (functions, types, indices, triggers) using built-in migration
mechanism. Technically creates a sophistication layer on top of the
`RunSQL` Django operation.
## What it does
- Makes maintaining your SQL functions, custom composite types,
indices and triggers easier.
- Structures SQL into configuration of **SQL items**, that are
identified by names and divided among apps, just like models.
- Automatically gathers and persists changes of your custom SQL into
migrations using `makemigrations`.
- Properly executes backwards/forwards keeping integrity of database.
- Create -\> Drop -\> Recreate approach for changes to items that do
not support altering and require dropping and recreating.
- Dependencies system for SQL items, which solves the problem of
updating items, that rely on others (for example custom
types/functions that use other custom types), and require dropping
all dependency tree previously with further recreation.
## What it does not
- Does not parse SQL nor validate queries during `makemigrations` or
`migrate` because is database-agnostic. For this same reason setting
up proper dependencies is user\'s responsibility.
- Does not create `ALTER` queries for items that support this, for
example `ALTER TYPE` in Postgre SQL, because is database-agnostic.
In case your tools allow rolling all the changes through `ALTER`
queries, you can consider not using this app **or** restructure
migrations manually after creation by nesting generated operations
into `` `state_operations `` of `RunSQL`
\<<https://docs.djangoproject.com/en/1.8/ref/migration-operations/#runsql>\>[\_\_
that does ]{.title-ref}[ALTER]{.title-ref}\`.
- (**TODO**)During `migrate` does not restore full state of items for
analysis, thus does not notify about existing changes to schema that
are not migrated **nor** does not recognize circular dependencies
during migration execution.
## Installation
Install from PyPi:
$ pip install django-migrate-sql-3
Add `migrate_sql` to `INSTALLED_APPS`:
``` python
INSTALLED_APPS = [
# ...
'migrate_sql',
]
```
App defines a custom `makemigrations` command, that inherits from
Django\'s core one, so in order `migrate_sql` app to kick in put it
after any other apps that redefine `makemigrations` command too.
## Usage
1) Create `sql_config.py` module to root of a target app you want to
manage custom SQL for.
2) Define SQL items in it (`sql_items`), for example:
``` python
# PostgreSQL example.
# Let's define a simple function and let `migrate_sql` manage it's changes.
from migrate_sql.config import SQLItem
sql_items = [
SQLItem(
'make_sum', # name of the item
'create or replace function make_sum(a int, b int) returns int as $$ '
'begin return a + b; end; '
'$$ language plpgsql;', # forward sql
reverse_sql='drop function make_sum(int, int);', # sql for removal
),
]
```
3) Create migration `./manage.py makemigrations`:
Migrations for 'app_name':
0002_auto_xxxx.py:
- Create SQL "make_sum"
You can take a look at content this generated:
``` python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import migrate_sql.operations
class Migration(migrations.Migration):
dependencies = [
('app_name', '0001_initial'),
]
operations = [
migrate_sql.operations.CreateSQL(
name='make_sum',
sql='create or replace function make_sum(a int, b int) returns int as $$ begin return a + b; end; $$ language plpgsql;',
reverse_sql='drop function make_sum(int, int);',
),
]
```
4) Execute migration `./manage.py migrate`:
Operations to perform:
Apply all migrations: app_name
Running migrations:
Rendering model states... DONE
Applying app_name.0002_xxxx... OK
Check result in `./manage.py dbshell`:
db_name=# select make_sum(12, 15);
make_sum
----------
27
(1 row)
Now, say, you want to change the function implementation so that it
takes a custom type as argument:
5) Edit your `sql_config.py`:
``` python
# PostgreSQL example #2.
# Function and custom type.
from migrate_sql.config import SQLItem
sql_items = [
SQLItem(
'make_sum', # name of the item
'create or replace function make_sum(a mynum, b mynum) returns mynum as $$ '
'begin return (a.num + b.num, 'result')::mynum; end; '
'$$ language plpgsql;', # forward sql
reverse_sql='drop function make_sum(mynum, mynum);', # sql for removal
# depends on `mynum` since takes it as argument. we won't be able to drop function
# without dropping `mynum` first.
dependencies=[('app_name', 'mynum')],
),
SQLItem(
'mynum' # name of the item
'create type mynum as (num int, name varchar(20));', # forward sql
reverse_sql='drop type mynum;', # sql for removal
),
]
```
6) Generate migration `./manage.py makemigrations`:
```{=html}
<!-- -->
```
Migrations for 'app_name':
0003_xxxx:
- Reverse alter SQL "make_sum"
- Create SQL "mynum"
- Alter SQL "make_sum"
- Alter SQL state "make_sum"
You can take a look at the content this generated:
``` python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import migrate_sql.operations
class Migration(migrations.Migration):
dependencies = [
('app_name', '0002_xxxx'),
]
operations = [
migrate_sql.operations.ReverseAlterSQL(
name='make_sum',
sql='drop function make_sum(int, int);',
reverse_sql='create or replace function make_sum(a int, b int) returns int as $$ begin return a + b; end; $$ language plpgsql;',
),
migrate_sql.operations.CreateSQL(
name='mynum',
sql='create type mynum as (num int, name varchar(20));',
reverse_sql='drop type mynum;',
),
migrate_sql.operations.AlterSQL(
name='make_sum',
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;',
reverse_sql='drop function make_sum(mynum, mynum);',
),
migrate_sql.operations.AlterSQLState(
name='make_sum',
add_dependencies=(('app_name', 'mynum'),),
),
]
```
**\*NOTE:** Previous function is completely dropped before creation
because definition of it changed. `CREATE OR REPLACE` would create
another version of it, so `DROP` makes it clean.\*
**\*If you put \`\`replace=True\`\` as kwarg to an \`\`SQLItem\`\`
definition, it will NOT drop + create it, but just rerun forward SQL,
which is \`\`CREATE OR REPLACE\`\` in this example.**\*
7) Execute migration `./manage.py migrate`:
```{=html}
<!-- -->
```
Operations to perform:
Apply all migrations: app_name
Running migrations:
Rendering model states... DONE
Applying brands.0003_xxxx... OK
Check results:
db_name=# select make_sum((5, 'a')::mynum, (3, 'b')::mynum);
make_sum
------------
(8,result)
(1 row)
db_name=# select make_sum(12, 15);
ERROR: function make_sum(integer, integer) does not exist
LINE 1: select make_sum(12, 15);
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
For more examples see `tests`.
Feel free to [open new
issues](https://github.com/opengisch/django-migrate-sql/issues).
Raw data
{
"_id": null,
"home_page": null,
"name": "django-migrate-sql-3",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "postgres, service",
"author": null,
"author_email": "Bogdan Klichuk <klichuk@github.com>, Festicket <festicket@github.com>, Denis Rouzaud <info@opengis.ch>",
"download_url": "https://files.pythonhosted.org/packages/8f/30/43c4b6ec2654ccd03d2c2c1b6cb467eb77bc0260330d823d623081ad5b26/django_migrate_sql_3-3.0.2.tar.gz",
"platform": null,
"description": "# django-migrate-sql\n\n\nThis package is a fork of the `django-migrate-sql` package, originally\npublished by Bogdan Klichuk, later by @festicket. These packages appears unmaintained, so we\ndecided to start a fork as we depended on it. Most of the code is from\nhim.\n:::\n\n\nDjango Migrations support for raw SQL.\n\n## About\n\nThis tool implements mechanism for managing changes to custom SQL\nentities (functions, types, indices, triggers) using built-in migration\nmechanism. Technically creates a sophistication layer on top of the\n`RunSQL` Django operation.\n\n## What it does\n\n- Makes maintaining your SQL functions, custom composite types,\n indices and triggers easier.\n- Structures SQL into configuration of **SQL items**, that are\n identified by names and divided among apps, just like models.\n- Automatically gathers and persists changes of your custom SQL into\n migrations using `makemigrations`.\n- Properly executes backwards/forwards keeping integrity of database.\n- Create -\\> Drop -\\> Recreate approach for changes to items that do\n not support altering and require dropping and recreating.\n- Dependencies system for SQL items, which solves the problem of\n updating items, that rely on others (for example custom\n types/functions that use other custom types), and require dropping\n all dependency tree previously with further recreation.\n\n## What it does not\n\n- Does not parse SQL nor validate queries during `makemigrations` or\n `migrate` because is database-agnostic. For this same reason setting\n up proper dependencies is user\\'s responsibility.\n- Does not create `ALTER` queries for items that support this, for\n example `ALTER TYPE` in Postgre SQL, because is database-agnostic.\n In case your tools allow rolling all the changes through `ALTER`\n queries, you can consider not using this app **or** restructure\n migrations manually after creation by nesting generated operations\n into `` `state_operations `` of `RunSQL`\n \\<<https://docs.djangoproject.com/en/1.8/ref/migration-operations/#runsql>\\>[\\_\\_\n that does ]{.title-ref}[ALTER]{.title-ref}\\`.\n- (**TODO**)During `migrate` does not restore full state of items for\n analysis, thus does not notify about existing changes to schema that\n are not migrated **nor** does not recognize circular dependencies\n during migration execution.\n\n## Installation\n\nInstall from PyPi:\n\n $ pip install django-migrate-sql-3\n\nAdd `migrate_sql` to `INSTALLED_APPS`:\n\n``` python\nINSTALLED_APPS = [\n # ...\n 'migrate_sql',\n]\n```\n\nApp defines a custom `makemigrations` command, that inherits from\nDjango\\'s core one, so in order `migrate_sql` app to kick in put it\nafter any other apps that redefine `makemigrations` command too.\n\n## Usage\n\n1) Create `sql_config.py` module to root of a target app you want to\n manage custom SQL for.\n2) Define SQL items in it (`sql_items`), for example:\n\n``` python\n# PostgreSQL example.\n# Let's define a simple function and let `migrate_sql` manage it's changes.\n\nfrom migrate_sql.config import SQLItem\n\nsql_items = [\n SQLItem(\n 'make_sum', # name of the item\n 'create or replace function make_sum(a int, b int) returns int as $$ '\n 'begin return a + b; end; '\n '$$ language plpgsql;', # forward sql\n reverse_sql='drop function make_sum(int, int);', # sql for removal\n ),\n]\n```\n\n3) Create migration `./manage.py makemigrations`:\n\n Migrations for 'app_name':\n 0002_auto_xxxx.py:\n - Create SQL \"make_sum\"\n\nYou can take a look at content this generated:\n\n``` python\n# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\nfrom django.db import migrations, models\nimport migrate_sql.operations\n\n\nclass Migration(migrations.Migration):\n dependencies = [\n ('app_name', '0001_initial'),\n ]\n operations = [\n migrate_sql.operations.CreateSQL(\n name='make_sum',\n sql='create or replace function make_sum(a int, b int) returns int as $$ begin return a + b; end; $$ language plpgsql;',\n reverse_sql='drop function make_sum(int, int);',\n ),\n ]\n```\n\n4) Execute migration `./manage.py migrate`:\n\n Operations to perform:\n Apply all migrations: app_name\n Running migrations:\n Rendering model states... DONE\n Applying app_name.0002_xxxx... OK\n\nCheck result in `./manage.py dbshell`:\n\n db_name=# select make_sum(12, 15);\n make_sum\n ----------\n 27\n (1 row)\n\nNow, say, you want to change the function implementation so that it\ntakes a custom type as argument:\n\n5) Edit your `sql_config.py`:\n\n``` python\n# PostgreSQL example #2.\n# Function and custom type.\n\nfrom migrate_sql.config import SQLItem\n\nsql_items = [\n SQLItem(\n 'make_sum', # name of the item\n 'create or replace function make_sum(a mynum, b mynum) returns mynum as $$ '\n 'begin return (a.num + b.num, 'result')::mynum; end; '\n '$$ language plpgsql;', # forward sql\n reverse_sql='drop function make_sum(mynum, mynum);', # sql for removal\n # depends on `mynum` since takes it as argument. we won't be able to drop function\n # without dropping `mynum` first.\n dependencies=[('app_name', 'mynum')],\n ),\n SQLItem(\n 'mynum' # name of the item\n 'create type mynum as (num int, name varchar(20));', # forward sql\n reverse_sql='drop type mynum;', # sql for removal\n ),\n]\n```\n\n6) Generate migration `./manage.py makemigrations`:\n\n```{=html}\n<!-- -->\n```\n Migrations for 'app_name':\n 0003_xxxx:\n - Reverse alter SQL \"make_sum\"\n - Create SQL \"mynum\"\n - Alter SQL \"make_sum\"\n - Alter SQL state \"make_sum\"\n\nYou can take a look at the content this generated:\n\n``` python\n# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\nfrom django.db import migrations, models\nimport migrate_sql.operations\n\n\nclass Migration(migrations.Migration):\n dependencies = [\n ('app_name', '0002_xxxx'),\n ]\n operations = [\n migrate_sql.operations.ReverseAlterSQL(\n name='make_sum',\n sql='drop function make_sum(int, int);',\n reverse_sql='create or replace function make_sum(a int, b int) returns int as $$ begin return a + b; end; $$ language plpgsql;',\n ),\n migrate_sql.operations.CreateSQL(\n name='mynum',\n sql='create type mynum as (num int, name varchar(20));',\n reverse_sql='drop type mynum;',\n ),\n migrate_sql.operations.AlterSQL(\n name='make_sum',\n 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;',\n reverse_sql='drop function make_sum(mynum, mynum);',\n ),\n migrate_sql.operations.AlterSQLState(\n name='make_sum',\n add_dependencies=(('app_name', 'mynum'),),\n ),\n ]\n```\n\n**\\*NOTE:** Previous function is completely dropped before creation\nbecause definition of it changed. `CREATE OR REPLACE` would create\nanother version of it, so `DROP` makes it clean.\\*\n\n**\\*If you put \\`\\`replace=True\\`\\` as kwarg to an \\`\\`SQLItem\\`\\`\ndefinition, it will NOT drop + create it, but just rerun forward SQL,\nwhich is \\`\\`CREATE OR REPLACE\\`\\` in this example.**\\*\n\n7) Execute migration `./manage.py migrate`:\n\n```{=html}\n<!-- -->\n```\n Operations to perform:\n Apply all migrations: app_name\n Running migrations:\n Rendering model states... DONE\n Applying brands.0003_xxxx... OK\n\nCheck results:\n\n db_name=# select make_sum((5, 'a')::mynum, (3, 'b')::mynum);\n make_sum \n ------------\n (8,result)\n (1 row)\n\n db_name=# select make_sum(12, 15);\n ERROR: function make_sum(integer, integer) does not exist\n LINE 1: select make_sum(12, 15);\n ^\n HINT: No function matches the given name and argument types. You might need to add explicit type casts.\n\nFor more examples see `tests`.\n\nFeel free to [open new\nissues](https://github.com/opengisch/django-migrate-sql/issues).\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "A package parsing the PostgreSQL connection service file",
"version": "3.0.2",
"project_urls": {
"homepage": "https://github.com/opengisch/django-migrate-sql",
"repository": "https://github.com/opengisch/django-migrate-sql",
"tracker": "https://github.com/opengisch/django-migrate-sql/issues"
},
"split_keywords": [
"postgres",
" service"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9a28efd044461cf09ce9a4c2f2c68b9a7a38d08f28c39174a413c936b27868c3",
"md5": "8ab005f73cd7a095ead2c20372f30324",
"sha256": "d5e04cb5b51f63a7260783445b9bc4b4eaf160e2b7faec1146f34b587f189dee"
},
"downloads": -1,
"filename": "django_migrate_sql_3-3.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8ab005f73cd7a095ead2c20372f30324",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 12673,
"upload_time": "2024-04-19T09:51:10",
"upload_time_iso_8601": "2024-04-19T09:51:10.355786Z",
"url": "https://files.pythonhosted.org/packages/9a/28/efd044461cf09ce9a4c2f2c68b9a7a38d08f28c39174a413c936b27868c3/django_migrate_sql_3-3.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8f3043c4b6ec2654ccd03d2c2c1b6cb467eb77bc0260330d823d623081ad5b26",
"md5": "ef3db18e5dbfb80ac6d4caa4b0cbd726",
"sha256": "486770e7f4c670c0fbbc7937c57b9bb614db372624dce67657387c9f7c1da257"
},
"downloads": -1,
"filename": "django_migrate_sql_3-3.0.2.tar.gz",
"has_sig": false,
"md5_digest": "ef3db18e5dbfb80ac6d4caa4b0cbd726",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 25082,
"upload_time": "2024-04-19T09:51:12",
"upload_time_iso_8601": "2024-04-19T09:51:12.916180Z",
"url": "https://files.pythonhosted.org/packages/8f/30/43c4b6ec2654ccd03d2c2c1b6cb467eb77bc0260330d823d623081ad5b26/django_migrate_sql_3-3.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-19 09:51:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "opengisch",
"github_project": "django-migrate-sql",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "django-migrate-sql-3"
}