gn2pg_client 1.9.0.dev0__tar.gz → 1.10.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.
- gn2pg_client-1.10.0/PKG-INFO +107 -0
- gn2pg_client-1.10.0/README.md +58 -0
- gn2pg_client-1.10.0/gn2pg/alembic/env.py +72 -0
- gn2pg_client-1.10.0/gn2pg/alembic/script.py.mako +25 -0
- gn2pg_client-1.10.0/gn2pg/alembic/versions/20260818_01_initial_schema.py +134 -0
- gn2pg_client-1.10.0/gn2pg/api.py +330 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/admin_views.py +0 -1
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/app.py +2 -2
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/config.py +4 -2
- gn2pg_client-1.10.0/gn2pg/app/models.py +33 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/check_conf.py +102 -26
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/data/gn2pgconfig.toml +8 -3
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/data/to_gnsynthese.sql +284 -112
- gn2pg_client-1.10.0/gn2pg/database/__init__.py +5 -0
- gn2pg_client-1.10.0/gn2pg/database/migrations.py +208 -0
- gn2pg_client-1.10.0/gn2pg/database/tables.py +102 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/download.py +217 -105
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/helpers.py +46 -30
- gn2pg_client-1.9.0.dev0/gn2pg/locale/fr_FR/LC_MESSAGES/gn2pg.po~ → gn2pg_client-1.10.0/gn2pg/locale/fr_FR/LC_MESSAGES/gn2pg.po +293 -152
- gn2pg_client-1.9.0.dev0/gn2pg/locale/fr_FR/LC_MESSAGES/gn2pg.po → gn2pg_client-1.10.0/gn2pg/locale/fr_FR/LC_MESSAGES/gn2pg.po~ +138 -89
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/main.py +57 -13
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/store_postgresql.py +311 -351
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/utils.py +16 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/pyproject.toml +19 -18
- gn2pg_client-1.9.0.dev0/PKG-INFO +0 -251
- gn2pg_client-1.9.0.dev0/README.md +0 -204
- gn2pg_client-1.9.0.dev0/gn2pg/api.py +0 -252
- gn2pg_client-1.9.0.dev0/gn2pg/app/models.py +0 -69
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/LICENSE +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/__init__.py +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/__init__.py +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/database.py +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/env.py +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/index.py +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/static/css/custom_flaks_admin.css +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/static/img/src_gn2pg.png +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/templates/admin/master.html +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/templates/index.html +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/utils/__init__.py +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/app/utils/admin_views.py +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/data/__init__.py +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/env.py +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/locale/en_US/LC_MESAGES/gn2pg.po +0 -0
- {gn2pg_client-1.9.0.dev0 → gn2pg_client-1.10.0}/gn2pg/logger.py +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gn2pg_client
|
|
3
|
+
Version: 1.10.0
|
|
4
|
+
Summary: Import tool from GeoNature to a PostgreSQL database through Export module API (client side)
|
|
5
|
+
License: AGPL-3.0-or-later
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: GeoNature,Export,SINP,opendata,biodiversity
|
|
8
|
+
Author: Collectif
|
|
9
|
+
Maintainer: lpofredc
|
|
10
|
+
Maintainer-email: frederic.cloitre@lpo.fr
|
|
11
|
+
Requires-Python: >=3.10,<4.0
|
|
12
|
+
Classifier: Development Status :: 1 - Planning
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
|
|
16
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
17
|
+
Classifier: Natural Language :: French
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
26
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
27
|
+
Classifier: Topic :: Documentation
|
|
28
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
29
|
+
Classifier: Topic :: System :: Installation/Setup
|
|
30
|
+
Classifier: Topic :: System :: Software Distribution
|
|
31
|
+
Provides-Extra: dashboard
|
|
32
|
+
Requires-Dist: alembic (>=1.16,<2.0)
|
|
33
|
+
Requires-Dist: coloredlogs (>=0.0.0)
|
|
34
|
+
Requires-Dist: flask (>=2,<3) ; extra == "dashboard"
|
|
35
|
+
Requires-Dist: flask-admin (>=1,<2) ; extra == "dashboard"
|
|
36
|
+
Requires-Dist: flask-sqlalchemy (>=3,<4) ; extra == "dashboard"
|
|
37
|
+
Requires-Dist: gunicorn (>=0.0.0) ; extra == "dashboard"
|
|
38
|
+
Requires-Dist: psycopg2-binary (>=2,<3)
|
|
39
|
+
Requires-Dist: python-decouple (>=3.8,<4.0) ; extra == "dashboard"
|
|
40
|
+
Requires-Dist: python-dotenv (>=1,<2) ; extra == "dashboard"
|
|
41
|
+
Requires-Dist: requests (>=2,<3)
|
|
42
|
+
Requires-Dist: schema (>=0,<1)
|
|
43
|
+
Requires-Dist: sqlalchemy (>=2.0,<3.0)
|
|
44
|
+
Requires-Dist: toml (>=0,<1)
|
|
45
|
+
Project-URL: Documentation, https://lpoaura.github.io/GN2PG/
|
|
46
|
+
Project-URL: Homepage, https://github.com/lpoaura/gn2gn_client/
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# GN2PG Client
|
|
50
|
+
|
|
51
|
+

|
|
52
|
+

|
|
53
|
+

|
|
54
|
+

|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
This project provides an import data from [GeoNature] instances to a PostgreSQL database (client side).
|
|
58
|
+
Widely inspired from [ClientApiVN](https://framagit.org/lpo/Client_API_VN/)
|
|
59
|
+
|
|
60
|
+
> [!WARNING]
|
|
61
|
+
> The minimum version of the source GeoNature instance required for the incremental update must be a version 2.12.0
|
|
62
|
+
|
|
63
|
+

|
|
64
|
+
|
|
65
|
+
## Project Setup
|
|
66
|
+
|
|
67
|
+
GN2PG Client can be installed by running `pip`. It requires Python 3.10 or above to run.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install gn2pg-client
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Issues
|
|
74
|
+
|
|
75
|
+
Please report any bugs or requests that you have using the [GitHub issue tracker](https://github.com/lpoaura/gn2pg_client/issues)!
|
|
76
|
+
|
|
77
|
+
## [HowTo](https://lpoaura.github.io/GN2PG/usage/howto.html)
|
|
78
|
+
|
|
79
|
+
## [Contributing](https://lpoaura.github.io/GN2PG/development/contribute.html)
|
|
80
|
+
|
|
81
|
+
## Licence
|
|
82
|
+
|
|
83
|
+
[GNU AGPLv3](https://www.gnu.org/licenses/gpl.html)
|
|
84
|
+
|
|
85
|
+
## Team
|
|
86
|
+
|
|
87
|
+
<a href="">
|
|
88
|
+
<img height="100px" src="https://auvergne-rhone-alpes.lpo.fr/wp-content/uploads/LPO_AuRA.svg" title="DREAL AuRA">
|
|
89
|
+
</a>
|
|
90
|
+
|
|
91
|
+
[@lpofredc](https://github.com/lpofredc/) ([LPO Auvergne-Rhône-Alpes](https://github.com/lpoaura/)), lead developer
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
<a href="https://github.com/lpoaura/GN2PG/graphs/contributors">
|
|
96
|
+
<img src="https://contrib.rocks/image?repo=lpoaura/GN2PG" />
|
|
97
|
+
</a>
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
With the financial support of the [DREAL Auvergne-Rhône-Alpes](http://www.auvergne-rhone-alpes.developpement-durable.gouv.fr/) and the [Office français de la biodiversité](https://www.ofb.gouv.fr/).
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
<img height="100px" src="https://data.lpo-aura.org/web/images/blocmarque_pref_region_auvergne_rhone_alpes_rvb_web.png" title="DREAL AuRA"> <img height="100px" src="https://www.ofb.gouv.fr/sites/default/files/logo-ofb.png" title="OFB" style="padding-left:10px;">
|
|
105
|
+
|
|
106
|
+
[geonature]: https://geonature.fr
|
|
107
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# GN2PG Client
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
This project provides an import data from [GeoNature] instances to a PostgreSQL database (client side).
|
|
10
|
+
Widely inspired from [ClientApiVN](https://framagit.org/lpo/Client_API_VN/)
|
|
11
|
+
|
|
12
|
+
> [!WARNING]
|
|
13
|
+
> The minimum version of the source GeoNature instance required for the incremental update must be a version 2.12.0
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
## Project Setup
|
|
18
|
+
|
|
19
|
+
GN2PG Client can be installed by running `pip`. It requires Python 3.10 or above to run.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install gn2pg-client
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Issues
|
|
26
|
+
|
|
27
|
+
Please report any bugs or requests that you have using the [GitHub issue tracker](https://github.com/lpoaura/gn2pg_client/issues)!
|
|
28
|
+
|
|
29
|
+
## [HowTo](https://lpoaura.github.io/GN2PG/usage/howto.html)
|
|
30
|
+
|
|
31
|
+
## [Contributing](https://lpoaura.github.io/GN2PG/development/contribute.html)
|
|
32
|
+
|
|
33
|
+
## Licence
|
|
34
|
+
|
|
35
|
+
[GNU AGPLv3](https://www.gnu.org/licenses/gpl.html)
|
|
36
|
+
|
|
37
|
+
## Team
|
|
38
|
+
|
|
39
|
+
<a href="">
|
|
40
|
+
<img height="100px" src="https://auvergne-rhone-alpes.lpo.fr/wp-content/uploads/LPO_AuRA.svg" title="DREAL AuRA">
|
|
41
|
+
</a>
|
|
42
|
+
|
|
43
|
+
[@lpofredc](https://github.com/lpofredc/) ([LPO Auvergne-Rhône-Alpes](https://github.com/lpoaura/)), lead developer
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
<a href="https://github.com/lpoaura/GN2PG/graphs/contributors">
|
|
48
|
+
<img src="https://contrib.rocks/image?repo=lpoaura/GN2PG" />
|
|
49
|
+
</a>
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
With the financial support of the [DREAL Auvergne-Rhône-Alpes](http://www.auvergne-rhone-alpes.developpement-durable.gouv.fr/) and the [Office français de la biodiversité](https://www.ofb.gouv.fr/).
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
<img height="100px" src="https://data.lpo-aura.org/web/images/blocmarque_pref_region_auvergne_rhone_alpes_rvb_web.png" title="DREAL AuRA"> <img height="100px" src="https://www.ofb.gouv.fr/sites/default/files/logo-ofb.png" title="OFB" style="padding-left:10px;">
|
|
57
|
+
|
|
58
|
+
[geonature]: https://geonature.fr
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Alembic environment for GN2PG's configurable import schema."""
|
|
2
|
+
|
|
3
|
+
# Alembic exposes context operations dynamically at migration runtime.
|
|
4
|
+
# pylint: disable=no-member
|
|
5
|
+
|
|
6
|
+
from alembic import context
|
|
7
|
+
from sqlalchemy import engine_from_config, pool, text
|
|
8
|
+
from sqlalchemy.dialects import postgresql
|
|
9
|
+
|
|
10
|
+
from gn2pg.database import build_metadata
|
|
11
|
+
|
|
12
|
+
config = context.config
|
|
13
|
+
schema = config.attributes.get("schema", "gn2pg_import")
|
|
14
|
+
target_metadata = build_metadata(schema)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def include_name(name, object_type, parent_names) -> bool:
|
|
18
|
+
"""Restrict reflection to the configured GN2PG schema."""
|
|
19
|
+
if object_type == "schema":
|
|
20
|
+
return name == schema
|
|
21
|
+
if object_type == "table":
|
|
22
|
+
return parent_names.get("schema_name") == schema
|
|
23
|
+
return True
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def run_migrations_offline() -> None:
|
|
27
|
+
"""Run migrations without creating an Engine."""
|
|
28
|
+
context.configure(
|
|
29
|
+
url=config.get_main_option("sqlalchemy.url"),
|
|
30
|
+
target_metadata=target_metadata,
|
|
31
|
+
literal_binds=True,
|
|
32
|
+
dialect_opts={"paramstyle": "named"},
|
|
33
|
+
include_schemas=True,
|
|
34
|
+
include_name=include_name,
|
|
35
|
+
version_table="alembic_version",
|
|
36
|
+
version_table_schema=schema,
|
|
37
|
+
schema=schema,
|
|
38
|
+
)
|
|
39
|
+
quoted_schema = postgresql.dialect().identifier_preparer.quote(schema)
|
|
40
|
+
context.execute(f"CREATE SCHEMA IF NOT EXISTS {quoted_schema}")
|
|
41
|
+
with context.begin_transaction():
|
|
42
|
+
context.run_migrations()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def run_migrations_online() -> None:
|
|
46
|
+
"""Run migrations with a live database connection."""
|
|
47
|
+
connectable = engine_from_config(
|
|
48
|
+
config.get_section(config.config_ini_section, {}),
|
|
49
|
+
prefix="sqlalchemy.",
|
|
50
|
+
poolclass=pool.NullPool,
|
|
51
|
+
)
|
|
52
|
+
with connectable.connect() as connection:
|
|
53
|
+
quoted_schema = connection.dialect.identifier_preparer.quote(schema)
|
|
54
|
+
connection.execute(text(f"CREATE SCHEMA IF NOT EXISTS {quoted_schema}"))
|
|
55
|
+
connection.commit()
|
|
56
|
+
context.configure(
|
|
57
|
+
connection=connection,
|
|
58
|
+
target_metadata=target_metadata,
|
|
59
|
+
include_schemas=True,
|
|
60
|
+
include_name=include_name,
|
|
61
|
+
version_table="alembic_version",
|
|
62
|
+
version_table_schema=schema,
|
|
63
|
+
schema=schema,
|
|
64
|
+
)
|
|
65
|
+
with context.begin_transaction():
|
|
66
|
+
context.run_migrations()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
if context.is_offline_mode():
|
|
70
|
+
run_migrations_offline()
|
|
71
|
+
else:
|
|
72
|
+
run_migrations_online()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""${message}
|
|
2
|
+
|
|
3
|
+
Revision ID: ${up_revision}
|
|
4
|
+
Revises: ${down_revision | comma,n}
|
|
5
|
+
Create Date: ${create_date}
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Optional, Sequence, Union
|
|
9
|
+
|
|
10
|
+
from alembic import op
|
|
11
|
+
import sqlalchemy as sa
|
|
12
|
+
${imports if imports else ""}
|
|
13
|
+
|
|
14
|
+
revision: str = ${repr(up_revision)}
|
|
15
|
+
down_revision: Optional[str] = ${repr(down_revision)}
|
|
16
|
+
branch_labels: Optional[Union[str, Sequence[str]]] = ${repr(branch_labels)}
|
|
17
|
+
depends_on: Optional[Union[str, Sequence[str]]] = ${repr(depends_on)}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade() -> None:
|
|
21
|
+
${upgrades if upgrades else "pass"}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def downgrade() -> None:
|
|
25
|
+
${downgrades if downgrades else "pass"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""Create the initial GN2PG import schema.
|
|
2
|
+
|
|
3
|
+
Revision ID: 20260818_01
|
|
4
|
+
Revises: None
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# pylint: disable=invalid-name,no-member
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
from sqlalchemy.dialects import postgresql
|
|
12
|
+
|
|
13
|
+
revision = "20260818_01"
|
|
14
|
+
down_revision = None
|
|
15
|
+
branch_labels = None
|
|
16
|
+
depends_on = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _schema() -> str:
|
|
20
|
+
return op.get_context().opts.get("schema", "gn2pg_import")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _index(schema: str, table: str, column: str) -> str:
|
|
24
|
+
return f"ix_{schema}_{table}_{column}"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def upgrade() -> None:
|
|
28
|
+
"""Create extensions and an immutable snapshot of the initial schema."""
|
|
29
|
+
schema = _schema()
|
|
30
|
+
op.execute('CREATE EXTENSION IF NOT EXISTS "pgcrypto"')
|
|
31
|
+
op.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"')
|
|
32
|
+
op.create_table(
|
|
33
|
+
"import_log",
|
|
34
|
+
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
|
|
35
|
+
sa.Column("source", sa.String(), nullable=False),
|
|
36
|
+
sa.Column("controler", sa.String(), nullable=False),
|
|
37
|
+
sa.Column("xfer_type", sa.String(), nullable=True),
|
|
38
|
+
sa.Column("xfer_status", sa.String(), nullable=True),
|
|
39
|
+
sa.Column("xfer_start_ts", sa.DateTime(), nullable=False),
|
|
40
|
+
sa.Column("xfer_end_ts", sa.DateTime(), nullable=True),
|
|
41
|
+
sa.Column("api_count_items", sa.Integer(), server_default=sa.text("0"), nullable=False),
|
|
42
|
+
sa.Column("api_count_errors", sa.Integer(), server_default=sa.text("0"), nullable=False),
|
|
43
|
+
sa.Column("data_count_upserts", sa.Integer(), server_default=sa.text("0"), nullable=False),
|
|
44
|
+
sa.Column("data_count_delete", sa.Integer(), server_default=sa.text("0"), nullable=False),
|
|
45
|
+
sa.Column("data_count_errors", sa.Integer(), server_default=sa.text("0"), nullable=False),
|
|
46
|
+
sa.Column(
|
|
47
|
+
"metadata_count_upserts", sa.Integer(), server_default=sa.text("0"), nullable=False
|
|
48
|
+
),
|
|
49
|
+
sa.Column(
|
|
50
|
+
"metadata_count_errors", sa.Integer(), server_default=sa.text("0"), nullable=False
|
|
51
|
+
),
|
|
52
|
+
sa.Column(
|
|
53
|
+
"xfer_filters",
|
|
54
|
+
postgresql.JSONB(astext_type=sa.Text()),
|
|
55
|
+
server_default=sa.text("'{}'::jsonb"),
|
|
56
|
+
nullable=True,
|
|
57
|
+
),
|
|
58
|
+
sa.Column("comment", sa.Text(), nullable=True),
|
|
59
|
+
sa.PrimaryKeyConstraint("id"),
|
|
60
|
+
schema=schema,
|
|
61
|
+
)
|
|
62
|
+
op.create_index(
|
|
63
|
+
_index(schema, "import_log", "source"), "import_log", ["source"], schema=schema
|
|
64
|
+
)
|
|
65
|
+
op.create_index(
|
|
66
|
+
_index(schema, "import_log", "xfer_type"), "import_log", ["xfer_type"], schema=schema
|
|
67
|
+
)
|
|
68
|
+
op.create_table(
|
|
69
|
+
"error_log",
|
|
70
|
+
sa.Column("source", sa.String(), nullable=False),
|
|
71
|
+
sa.Column("uuid", postgresql.UUID(), nullable=False),
|
|
72
|
+
sa.Column("controler", sa.String(), nullable=False),
|
|
73
|
+
sa.Column("last_ts", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
|
|
74
|
+
sa.Column("item", postgresql.JSONB(astext_type=sa.Text()), nullable=True),
|
|
75
|
+
sa.Column("error", sa.String(), nullable=True),
|
|
76
|
+
sa.Column("import_id", sa.Integer(), nullable=True),
|
|
77
|
+
sa.ForeignKeyConstraint(
|
|
78
|
+
["import_id"],
|
|
79
|
+
[f"{schema}.import_log.id"],
|
|
80
|
+
onupdate="CASCADE",
|
|
81
|
+
ondelete="CASCADE",
|
|
82
|
+
),
|
|
83
|
+
schema=schema,
|
|
84
|
+
)
|
|
85
|
+
op.create_index(
|
|
86
|
+
_index(schema, "error_log", "import_id"), "error_log", ["import_id"], schema=schema
|
|
87
|
+
)
|
|
88
|
+
op.create_index(_index(schema, "error_log", "uuid"), "error_log", ["uuid"], schema=schema)
|
|
89
|
+
op.create_table(
|
|
90
|
+
"data_json",
|
|
91
|
+
sa.Column("source", sa.String(), nullable=False),
|
|
92
|
+
sa.Column("controler", sa.String(), nullable=False),
|
|
93
|
+
sa.Column("type", sa.String(), nullable=False),
|
|
94
|
+
sa.Column("id_data", sa.Integer(), nullable=False),
|
|
95
|
+
sa.Column("uuid", postgresql.UUID(), nullable=True),
|
|
96
|
+
sa.Column("item", postgresql.JSONB(astext_type=sa.Text()), nullable=False),
|
|
97
|
+
sa.Column("update_ts", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
|
|
98
|
+
sa.Column("import_id", sa.Integer(), nullable=True),
|
|
99
|
+
sa.ForeignKeyConstraint(["import_id"], [f"{schema}.import_log.id"], onupdate="CASCADE"),
|
|
100
|
+
sa.PrimaryKeyConstraint("id_data", "source", "type", name="pk_source_data"),
|
|
101
|
+
sa.UniqueConstraint("uuid", name="unique_uuid"),
|
|
102
|
+
schema=schema,
|
|
103
|
+
)
|
|
104
|
+
op.create_index(
|
|
105
|
+
_index(schema, "data_json", "id_data"), "data_json", ["id_data"], schema=schema
|
|
106
|
+
)
|
|
107
|
+
op.create_index(_index(schema, "data_json", "uuid"), "data_json", ["uuid"], schema=schema)
|
|
108
|
+
op.create_table(
|
|
109
|
+
"metadata_json",
|
|
110
|
+
sa.Column("source", sa.String(), nullable=False),
|
|
111
|
+
sa.Column("controler", sa.String(), nullable=False),
|
|
112
|
+
sa.Column("type", sa.String(), nullable=False),
|
|
113
|
+
sa.Column("level", sa.String(), nullable=False),
|
|
114
|
+
sa.Column("uuid", postgresql.UUID(), nullable=False),
|
|
115
|
+
sa.Column("item", postgresql.JSONB(astext_type=sa.Text()), nullable=False),
|
|
116
|
+
sa.Column("update_ts", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
|
|
117
|
+
sa.Column("import_id", sa.Integer(), nullable=True),
|
|
118
|
+
sa.ForeignKeyConstraint(["import_id"], [f"{schema}.import_log.id"], onupdate="CASCADE"),
|
|
119
|
+
sa.PrimaryKeyConstraint("uuid", "source", name="pk_source_metadata"),
|
|
120
|
+
sa.UniqueConstraint("uuid", name="metadata_unique_uuid"),
|
|
121
|
+
schema=schema,
|
|
122
|
+
)
|
|
123
|
+
op.create_index(
|
|
124
|
+
_index(schema, "metadata_json", "uuid"), "metadata_json", ["uuid"], schema=schema
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def downgrade() -> None:
|
|
129
|
+
"""Drop GN2PG tables while preserving the schema and shared extensions."""
|
|
130
|
+
schema = _schema()
|
|
131
|
+
op.drop_table("metadata_json", schema=schema)
|
|
132
|
+
op.drop_table("data_json", schema=schema)
|
|
133
|
+
op.drop_table("error_log", schema=schema)
|
|
134
|
+
op.drop_table("import_log", schema=schema)
|