Compare commits
161 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b2b49d93ae | |||
| 7bffa6cba6 | |||
| 0a1aee591a | |||
| a0f73e6a32 | |||
| e8a8ce2528 | |||
| b2c3d3a301 | |||
| 759eb906b9 | |||
| 41870ee2e2 | |||
| 0ac2485bff | |||
| eb16990b0b | |||
| ce103137a5 | |||
| 547cc6e4ae | |||
| 32d23a7073 | |||
| 7890b18568 | |||
| 90ff7eb793 | |||
| d07f3ed716 | |||
| 7d2ae48067 | |||
| 1d877545ae | |||
| 87f3764ebf | |||
| 3ae4d639ec | |||
| a5550091d3 | |||
| 61402c183e | |||
| 64e4392a92 | |||
| ae73d2f87f | |||
| 86e36bc64a | |||
| d1817a3611 | |||
| d465934818 | |||
| c353d5bcef | |||
| bdda586ccd | |||
| 0d989dcb2c | |||
| 2f84f76d89 | |||
| 3343524325 | |||
| 28ecb4d786 | |||
| 338da0208c | |||
| ec67340e66 | |||
| 1c0286eda0 | |||
| 7d5ff47e8e | |||
| 5046171b76 | |||
| f374ae426c | |||
| 2a375b0a6f | |||
| a5d7f89fcb | |||
| 96ccf30e46 | |||
| 38dad49bbd | |||
| f2be7d0a53 | |||
| 9b4afb845b | |||
| f4b5f3960c | |||
| 127ea49d74 | |||
| 30e1fd23d6 | |||
| df517cfbfa | |||
| ec6ac443fb | |||
| 11781dd70b | |||
| b9ab27523f | |||
| 331543d74b | |||
| e7ef5c3d32 | |||
| 1a6870b8fe | |||
| ad6ac13d50 | |||
| c976d94bdd | |||
| 5d7dea5a84 | |||
| e5e3d38365 | |||
| 1af2b695dc | |||
| bbb1207b27 | |||
| 9cfa91e091 | |||
| 87101d6b04 | |||
| 1f254ca775 | |||
| d884a761ad | |||
| cfe2e4b7b4 | |||
| c93660ec4a | |||
| 0a0d43aa9f | |||
| bc0836fc3c | |||
| e7b493d7c9 | |||
| 185cd86efb | |||
| 5ee2db267a | |||
| 26a4746898 | |||
| 2e0ec73317 | |||
| b061959b18 | |||
| 982da89861 | |||
| 4ec7923164 | |||
| 4bc556aec5 | |||
| e520a34fa5 | |||
| d741a88299 | |||
| 36eca08895 | |||
| da9b559752 | |||
| 6677fe1e23 | |||
| b85259c013 | |||
| bb21d6a364 | |||
| ec89230893 | |||
| 2fc9c88cd5 | |||
| 3435b4714e | |||
| 7b6280b6dc | |||
| 140f3cbdba | |||
| ac084c4e79 | |||
| 71592e883a | |||
| e60b91fd45 | |||
| aae01c010b | |||
| 5e4cd8978d | |||
| e120812eae | |||
| 25b2dc6cec | |||
| df4536741d | |||
| e9161e8c93 | |||
| 4ed61380de | |||
| 98be276bd1 | |||
| 96d575feb7 | |||
| 02d022295c | |||
| 985d224cb8 | |||
| 35068c0cb1 | |||
| 34cb6b210d | |||
| 061dac39f9 | |||
| be64b4959a | |||
| 311a2c328b | |||
| 935c64464a | |||
| 1dbf14f3bb | |||
| ed768a83d0 | |||
| f4e4c3efb3 | |||
| 81daa5d913 | |||
| 3e5ca3483e | |||
| c38d00a7cc | |||
| 1d898cb580 | |||
| 6204db8ae3 | |||
| 5189c12f43 | |||
| b573ae459e | |||
| 10666de488 | |||
| fd2f09fcf3 | |||
| 4a517bf7bf | |||
| 09042747a0 | |||
| 9cc7237bfb | |||
| a17d269adb | |||
| 00fd484669 | |||
| 4c0754ee01 | |||
| 3290a9936e | |||
| fa5469958e | |||
| 1327d1f7b2 | |||
| 8cc4af950e | |||
| ccb64c5c4d | |||
| 920811136e | |||
| c778997239 | |||
| f7d5d0ab1c | |||
| 33717bb055 | |||
| 7d65d3c5a2 | |||
| acba07aa0e | |||
| 233b2a2dab | |||
| 5005c3c978 | |||
| ba926ec2de | |||
| 19b6738e5d | |||
| d9ef550100 | |||
| baacd1c15c | |||
| 7415504926 | |||
| f0a2308bd9 | |||
| d070caae05 | |||
| f42761f359 | |||
| 768859b6b9 | |||
| 87b97f53b8 | |||
| 9bd1c07193 | |||
| b161109d65 | |||
| b546c9e97d | |||
| 5b96fcfc2a | |||
| 039aa60038 | |||
| 19dcc2d24b | |||
| 45bb985465 | |||
| bd972e30db | |||
| 07b6fa7c22 | |||
| 8ef59bc53f |
197 changed files with 23606 additions and 137 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,3 +1,6 @@
|
|||
*~
|
||||
*.pyc
|
||||
dist/
|
||||
docs/_build/
|
||||
style/dist/
|
||||
style/node_modules/
|
||||
|
|
|
|||
232
CHANGELOG.md
232
CHANGELOG.md
|
|
@ -5,6 +5,238 @@ All notable changes to WuttaFarm will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## v0.7.0 (2026-03-04)
|
||||
|
||||
### Feat
|
||||
|
||||
- expose "group membership" for assets
|
||||
- expose "current location" for assets
|
||||
- add schema, sync support for `Log.is_movement`
|
||||
- add schema, import support for `Asset.owners`
|
||||
- add schema, import support for `Log.quick`
|
||||
- show quantities when viewing log
|
||||
- add sync support for `MedicalLog.vet`
|
||||
- add schema, import support for `Log.quantities`
|
||||
- add schema, import support for `Log.groups`
|
||||
- add schema, import support for `Log.locations`
|
||||
- add sync support for `Log.is_group_assignment`
|
||||
- add support for exporting log status, timestamp to farmOS
|
||||
- add support for log 'owners'
|
||||
- add support for edit, import/export of plant type data
|
||||
- add way to create animal type when editing animal
|
||||
- add related version tables for asset/log revision history
|
||||
- improve mirror/deletion for assets, logs, animal types
|
||||
- auto-delete asset from farmOS if deleting via mirror app
|
||||
|
||||
### Fix
|
||||
|
||||
- show drupal ID column for asset types
|
||||
- remove unique constraint for `LandAsset.land_type_uuid`
|
||||
- move farmOS UUID field below the Drupal ID
|
||||
- add links for Parents column in All Assets grid
|
||||
- set timestamp for new log in quick eggs form
|
||||
- set default grid pagesize to 50
|
||||
- add placeholder for log 'quick' field
|
||||
- define log grid columns to match farmOS
|
||||
- make AllLogView inherit from LogMasterView
|
||||
- rename views for "all records" (all assets, all logs etc.)
|
||||
- ensure token refresh works regardless where API client is used
|
||||
- render links for Plant Type column in Plant Assets grid
|
||||
- fix land asset type
|
||||
- prevent edit for asset types, land types when app is mirror
|
||||
- add farmOS-style links for Parents column in Land Assets grid
|
||||
- remove unique constraint for `AnimalType.name`
|
||||
- prevent delete if animal type is still being referenced
|
||||
- add reminder to restart if changing integration mode
|
||||
- prevent edit for user farmos_uuid, drupal_id
|
||||
- remove 'contains' verb for sex filter
|
||||
- add enum, row hilite for log status
|
||||
- fix Sex field when empty and deleting an animal
|
||||
- add `get_farmos_client_for_user()` convenience function
|
||||
- use current user token for auto-sync within web app
|
||||
- set log type, status enums for log grids
|
||||
- add more default perms for first site admin user
|
||||
- only show quick form menu if perms allow
|
||||
- expose config for farmOS OAuth2 client_id and scope
|
||||
- add separate permission for each quick form view
|
||||
|
||||
## v0.6.0 (2026-02-25)
|
||||
|
||||
### Feat
|
||||
|
||||
- add common normalizer to simplify code in view, importer etc.
|
||||
- overhaul farmOS log views; add Eggs quick form
|
||||
- add basic CRUD for direct API views: animal types, animal assets
|
||||
- use 'include' API param for better Animal Assets grid data
|
||||
- add backend filters, sorting for farmOS animal types, assets
|
||||
- include/exclude certain views, menus based on integration mode
|
||||
- add Standard Quantities table, views, import
|
||||
- add Quantity Types table, views, import
|
||||
- add Units table, views, import/export
|
||||
|
||||
### Fix
|
||||
|
||||
- add `Notes` schema type
|
||||
- add grid filter for animal birthdate
|
||||
- add thumbnail to farmOS asset base view
|
||||
- add setting to toggle "farmOS-style grid links"
|
||||
- standardize a bit more for the farmOS Animal Assets view
|
||||
- set *default* instead of configured menu handler
|
||||
- expose farmOS integration mode, URL in app settings
|
||||
- reword some menu entries
|
||||
- add WuttaFarm -> farmOS export for Plant Assets
|
||||
- fix default admin user perms, per new log schema
|
||||
|
||||
## v0.5.0 (2026-02-18)
|
||||
|
||||
### Feat
|
||||
|
||||
- add `produces_eggs` flag for animal, group assets
|
||||
- add more assets (plant) and logs (harvest, medical, observation)
|
||||
- refactor log models, views to use generic/common base
|
||||
|
||||
### Fix
|
||||
|
||||
- rename db model modules, for better convention
|
||||
- add override for requests cert validation
|
||||
|
||||
## v0.4.1 (2026-02-17)
|
||||
|
||||
### Fix
|
||||
|
||||
- remove `AnimalType.changed` column
|
||||
|
||||
## v0.4.0 (2026-02-17)
|
||||
|
||||
### Feat
|
||||
|
||||
- add basic support for WuttaFarm → farmOS export
|
||||
- convert group assets to use common base/mixin
|
||||
- convert structure assets to use common base/mixin
|
||||
- convert land assets to use common base/mixin
|
||||
- add "generic" assets, new animal assets based on that
|
||||
|
||||
### Fix
|
||||
|
||||
- misc. field tweaks for asset forms
|
||||
- show warning when viewing an archived asset
|
||||
- fix some perms for all assets view
|
||||
- fix initial admin perms per route renaming
|
||||
- add parent relationships support for land assets
|
||||
- cleanup Land views to better match farmOS
|
||||
- cleanup Structure views to better match farmOS
|
||||
- cleanup Group views to better match farmOS
|
||||
- add / display thumbnail image for animals
|
||||
- improve handling of 'archived' records for grid/form views
|
||||
- use Male/Female dict enum for animal sex field
|
||||
- prevent direct edit of `farmos_uuid` and `drupal_id` fields
|
||||
- use same datetime display format as farmOS
|
||||
- convert `active` flag to `archived`
|
||||
- suppress output when user farmos/drupal keys are empty
|
||||
- customize page footer to mention farmOS
|
||||
|
||||
## v0.3.1 (2026-02-14)
|
||||
|
||||
### Fix
|
||||
|
||||
- update sterile, archived flags per farmOS 4.x
|
||||
|
||||
## v0.3.0 (2026-02-13)
|
||||
|
||||
### Feat
|
||||
|
||||
- add native table for Activity Logs; import from farmOS API
|
||||
- add native table for Groups; import from farmOS API
|
||||
- add native table for Animals; import from farmOS API
|
||||
- add native table for Structures; import from farmOS API
|
||||
- add native table for Land Assets; import from farmOS API
|
||||
- add native table for Log Types; import from farmOS API
|
||||
- add native table for Structure Types; import from farmOS API
|
||||
- add native table for Land Types; import from farmOS API
|
||||
- add native table for Asset Types; import from farmOS API
|
||||
- add extension table for Users; import from farmOS API
|
||||
- add native table for Animal Types; import from farmOS API
|
||||
- add "See raw JSON data" button for farmOS API views
|
||||
|
||||
### Fix
|
||||
|
||||
- always make 'farmos' system user in app setup
|
||||
- avoid error for Create User form
|
||||
- add more perms to Site Admin role in app setup
|
||||
- rename `drupal_internal_id` => `drupal_id`
|
||||
|
||||
## v0.2.3 (2026-02-08)
|
||||
|
||||
### Fix
|
||||
|
||||
- add custom (built) buefy css to repo
|
||||
|
||||
## v0.2.2 (2026-02-08)
|
||||
|
||||
### Fix
|
||||
|
||||
- update project links for PyPI
|
||||
|
||||
## v0.2.1 (2026-02-08)
|
||||
|
||||
### Fix
|
||||
|
||||
- run web app via uvicorn/ASGI by default
|
||||
|
||||
## v0.2.0 (2026-02-08)
|
||||
|
||||
### Feat
|
||||
|
||||
- add view for farmOS activity logs
|
||||
- add view for farmOS log types
|
||||
- add view for farmOS structure types
|
||||
- add view for farmOS land types
|
||||
- add view for farmOS land assets
|
||||
- add view for farmOS groups
|
||||
- add view for farmOS asset types
|
||||
- add view for farmOS structures
|
||||
- add view for farmOS animal types
|
||||
- add view for farmOS users
|
||||
|
||||
### Fix
|
||||
|
||||
- add pyramid_exclog dependency
|
||||
- add menu option, "Go to farmOS"
|
||||
- ensure Buefy version matches what we use for custom css
|
||||
|
||||
## v0.1.5 (2026-02-07)
|
||||
|
||||
### Fix
|
||||
|
||||
- fix built wheel to include custom buefy css
|
||||
|
||||
## v0.1.4 (2026-02-07)
|
||||
|
||||
### Fix
|
||||
|
||||
- add custom style to better match farmOS color scheme
|
||||
|
||||
## v0.1.3 (2026-02-06)
|
||||
|
||||
### Fix
|
||||
|
||||
- fix a couple more edge cases around oauth2 token refresh
|
||||
|
||||
## v0.1.2 (2026-02-06)
|
||||
|
||||
### Fix
|
||||
|
||||
- add support for farmOS/OAuth2 Authorization Code grant/workflow
|
||||
|
||||
## v0.1.1 (2026-02-05)
|
||||
|
||||
### Fix
|
||||
|
||||
- preserve oauth2 token so auto-refresh works correctly
|
||||
- customize app installer to configure farmos_url
|
||||
- add some more info when viewing animal
|
||||
- require minimum version for wuttaweb
|
||||
|
||||
## v0.1.0 (2026-02-03)
|
||||
|
||||
### Feat
|
||||
|
|
|
|||
12
README.md
12
README.md
|
|
@ -13,14 +13,4 @@ include:
|
|||
- possibly add more schema / extra features
|
||||
- possibly sync data back to farmOS
|
||||
|
||||
|
||||
## Quick Start
|
||||
|
||||
Make a virtual environment and install the app:
|
||||
|
||||
python3 -m venv .venv
|
||||
.venv/bin/pip install -e .
|
||||
.venv/bin/wuttafarm install
|
||||
|
||||
For more info see
|
||||
https://docs.wuttaproject.org/wuttjamaican/narr/install/index.html
|
||||
See full docs at https://docs.wuttaproject.org/wuttafarm/
|
||||
|
|
|
|||
20
docs/Makefile
Normal file
20
docs/Makefile
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
0
docs/_static/.keepme
vendored
Normal file
0
docs/_static/.keepme
vendored
Normal file
6
docs/api/wuttafarm.app.rst
Normal file
6
docs/api/wuttafarm.app.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.app``
|
||||
=================
|
||||
|
||||
.. automodule:: wuttafarm.app
|
||||
:members:
|
||||
6
docs/api/wuttafarm.auth.rst
Normal file
6
docs/api/wuttafarm.auth.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.auth``
|
||||
==================
|
||||
|
||||
.. automodule:: wuttafarm.auth
|
||||
:members:
|
||||
6
docs/api/wuttafarm.cli.base.rst
Normal file
6
docs/api/wuttafarm.cli.base.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.cli.base``
|
||||
======================
|
||||
|
||||
.. automodule:: wuttafarm.cli.base
|
||||
:members:
|
||||
6
docs/api/wuttafarm.cli.import_farmos.rst
Normal file
6
docs/api/wuttafarm.cli.import_farmos.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.cli.import_farmos``
|
||||
===============================
|
||||
|
||||
.. automodule:: wuttafarm.cli.import_farmos
|
||||
:members:
|
||||
6
docs/api/wuttafarm.cli.install.rst
Normal file
6
docs/api/wuttafarm.cli.install.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.cli.install``
|
||||
=========================
|
||||
|
||||
.. automodule:: wuttafarm.cli.install
|
||||
:members:
|
||||
6
docs/api/wuttafarm.cli.rst
Normal file
6
docs/api/wuttafarm.cli.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.cli``
|
||||
=================
|
||||
|
||||
.. automodule:: wuttafarm.cli
|
||||
:members:
|
||||
6
docs/api/wuttafarm.config.rst
Normal file
6
docs/api/wuttafarm.config.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.config``
|
||||
====================
|
||||
|
||||
.. automodule:: wuttafarm.config
|
||||
:members:
|
||||
6
docs/api/wuttafarm.db.model.rst
Normal file
6
docs/api/wuttafarm.db.model.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.db.model``
|
||||
======================
|
||||
|
||||
.. automodule:: wuttafarm.db.model
|
||||
:members:
|
||||
6
docs/api/wuttafarm.db.rst
Normal file
6
docs/api/wuttafarm.db.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.db``
|
||||
================
|
||||
|
||||
.. automodule:: wuttafarm.db
|
||||
:members:
|
||||
6
docs/api/wuttafarm.farmos.handler.rst
Normal file
6
docs/api/wuttafarm.farmos.handler.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.farmos.handler``
|
||||
============================
|
||||
|
||||
.. automodule:: wuttafarm.farmos.handler
|
||||
:members:
|
||||
6
docs/api/wuttafarm.farmos.rst
Normal file
6
docs/api/wuttafarm.farmos.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.farmos``
|
||||
====================
|
||||
|
||||
.. automodule:: wuttafarm.farmos
|
||||
:members:
|
||||
6
docs/api/wuttafarm.importing.farmos.rst
Normal file
6
docs/api/wuttafarm.importing.farmos.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.importing.farmos``
|
||||
==============================
|
||||
|
||||
.. automodule:: wuttafarm.importing.farmos
|
||||
:members:
|
||||
6
docs/api/wuttafarm.importing.rst
Normal file
6
docs/api/wuttafarm.importing.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.importing``
|
||||
=======================
|
||||
|
||||
.. automodule:: wuttafarm.importing
|
||||
:members:
|
||||
6
docs/api/wuttafarm.install.rst
Normal file
6
docs/api/wuttafarm.install.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.install``
|
||||
=====================
|
||||
|
||||
.. automodule:: wuttafarm.install
|
||||
:members:
|
||||
6
docs/api/wuttafarm.rst
Normal file
6
docs/api/wuttafarm.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm``
|
||||
=============
|
||||
|
||||
.. automodule:: wuttafarm
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.app.rst
Normal file
6
docs/api/wuttafarm.web.app.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.app``
|
||||
=====================
|
||||
|
||||
.. automodule:: wuttafarm.web.app
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.forms.rst
Normal file
6
docs/api/wuttafarm.web.forms.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.forms``
|
||||
=======================
|
||||
|
||||
.. automodule:: wuttafarm.web.forms
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.forms.schema.rst
Normal file
6
docs/api/wuttafarm.web.forms.schema.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.forms.schema``
|
||||
==============================
|
||||
|
||||
.. automodule:: wuttafarm.web.forms.schema
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.forms.widgets.rst
Normal file
6
docs/api/wuttafarm.web.forms.widgets.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.forms.widgets``
|
||||
===============================
|
||||
|
||||
.. automodule:: wuttafarm.web.forms.widgets
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.menus.rst
Normal file
6
docs/api/wuttafarm.web.menus.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.menus``
|
||||
=======================
|
||||
|
||||
.. automodule:: wuttafarm.web.menus
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.rst
Normal file
6
docs/api/wuttafarm.web.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web``
|
||||
=================
|
||||
|
||||
.. automodule:: wuttafarm.web
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.static.rst
Normal file
6
docs/api/wuttafarm.web.static.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.static``
|
||||
========================
|
||||
|
||||
.. automodule:: wuttafarm.web.static
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.subscribers.rst
Normal file
6
docs/api/wuttafarm.web.subscribers.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.subscribers``
|
||||
=============================
|
||||
|
||||
.. automodule:: wuttafarm.web.subscribers
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.util.rst
Normal file
6
docs/api/wuttafarm.web.util.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.util``
|
||||
======================
|
||||
|
||||
.. automodule:: wuttafarm.web.util
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.auth.rst
Normal file
6
docs/api/wuttafarm.web.views.auth.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.auth``
|
||||
============================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.auth
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.common.rst
Normal file
6
docs/api/wuttafarm.web.views.common.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.common``
|
||||
==============================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.common
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.animal_types.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.animal_types.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.animal_types``
|
||||
===========================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.animal_types
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.animals.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.animals.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.animals``
|
||||
======================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.animals
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.asset_types.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.asset_types.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.asset_types``
|
||||
==========================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.asset_types
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.groups.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.groups.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.groups``
|
||||
=====================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.groups
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.land_assets.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.land_assets.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.land_assets``
|
||||
==========================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.land_assets
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.land_types.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.land_types.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.land_types``
|
||||
=========================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.land_types
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.log_types.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.log_types.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.log_types``
|
||||
========================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.log_types
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.logs_activity.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.logs_activity.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.logs_activity``
|
||||
============================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.logs_activity
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.master.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.master.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.master``
|
||||
=====================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.master
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos``
|
||||
==============================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.structure_types.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.structure_types.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.structure_types``
|
||||
==============================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.structure_types
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.structures.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.structures.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.structures``
|
||||
=========================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.structures
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.farmos.users.rst
Normal file
6
docs/api/wuttafarm.web.views.farmos.users.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views.farmos.users``
|
||||
====================================
|
||||
|
||||
.. automodule:: wuttafarm.web.views.farmos.users
|
||||
:members:
|
||||
6
docs/api/wuttafarm.web.views.rst
Normal file
6
docs/api/wuttafarm.web.views.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
``wuttafarm.web.views``
|
||||
=======================
|
||||
|
||||
.. automodule:: wuttafarm.web.views
|
||||
:members:
|
||||
40
docs/conf.py
Normal file
40
docs/conf.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
from importlib.metadata import version as get_version
|
||||
|
||||
project = "WuttaFarm"
|
||||
copyright = "2026, Lance Edgar"
|
||||
author = "Lance Edgar"
|
||||
release = get_version("WuttaFarm")
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
extensions = [
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.viewcode",
|
||||
"sphinx.ext.todo",
|
||||
"sphinxcontrib.programoutput",
|
||||
]
|
||||
|
||||
templates_path = ["_templates"]
|
||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
||||
|
||||
intersphinx_mapping = {
|
||||
"wuttjamaican": ("https://docs.wuttaproject.org/wuttjamaican/", None),
|
||||
"wutta-continuum": ("https://docs.wuttaproject.org/wutta-continuum/", None),
|
||||
}
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
html_theme = "furo"
|
||||
html_static_path = ["_static"]
|
||||
84
docs/index.rst
Normal file
84
docs/index.rst
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
|
||||
WuttaFarm
|
||||
=========
|
||||
|
||||
This is a Python web app (built with `WuttaWeb`_), to integrate with
|
||||
and extend `farmOS`_.
|
||||
|
||||
.. _WuttaWeb: https://wuttaproject.org
|
||||
.. _farmOS: https://farmos.org
|
||||
|
||||
It is just an experiment so far; the ideas I hope to play with
|
||||
include:
|
||||
|
||||
- display farmOS data directly, via real-time API fetch
|
||||
- add "mirror" schema and sync data from farmOS to app DB (and display it)
|
||||
- possibly add more schema / extra features
|
||||
- possibly sync data back to farmOS
|
||||
|
||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
:target: https://github.com/psf/black
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Documentation:
|
||||
|
||||
narr/install
|
||||
narr/auth
|
||||
narr/features
|
||||
narr/cli
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Package API:
|
||||
|
||||
api/wuttafarm
|
||||
api/wuttafarm.app
|
||||
api/wuttafarm.auth
|
||||
api/wuttafarm.cli
|
||||
api/wuttafarm.cli.base
|
||||
api/wuttafarm.cli.import_farmos
|
||||
api/wuttafarm.cli.install
|
||||
api/wuttafarm.config
|
||||
api/wuttafarm.db
|
||||
api/wuttafarm.db.model
|
||||
api/wuttafarm.farmos
|
||||
api/wuttafarm.farmos.handler
|
||||
api/wuttafarm.importing
|
||||
api/wuttafarm.importing.farmos
|
||||
api/wuttafarm.install
|
||||
api/wuttafarm.web
|
||||
api/wuttafarm.web.app
|
||||
api/wuttafarm.web.forms
|
||||
api/wuttafarm.web.forms.schema
|
||||
api/wuttafarm.web.forms.widgets
|
||||
api/wuttafarm.web.menus
|
||||
api/wuttafarm.web.static
|
||||
api/wuttafarm.web.subscribers
|
||||
api/wuttafarm.web.util
|
||||
api/wuttafarm.web.views
|
||||
api/wuttafarm.web.views.auth
|
||||
api/wuttafarm.web.views.common
|
||||
api/wuttafarm.web.views.farmos
|
||||
api/wuttafarm.web.views.farmos.animals
|
||||
api/wuttafarm.web.views.farmos.animal_types
|
||||
api/wuttafarm.web.views.farmos.asset_types
|
||||
api/wuttafarm.web.views.farmos.groups
|
||||
api/wuttafarm.web.views.farmos.land_assets
|
||||
api/wuttafarm.web.views.farmos.land_types
|
||||
api/wuttafarm.web.views.farmos.logs_activity
|
||||
api/wuttafarm.web.views.farmos.log_types
|
||||
api/wuttafarm.web.views.farmos.master
|
||||
api/wuttafarm.web.views.farmos.structures
|
||||
api/wuttafarm.web.views.farmos.structure_types
|
||||
api/wuttafarm.web.views.farmos.users
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
35
docs/make.bat
Normal file
35
docs/make.bat
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=.
|
||||
set BUILDDIR=_build
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
58
docs/narr/auth.rst
Normal file
58
docs/narr/auth.rst
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
==============
|
||||
Authentication
|
||||
==============
|
||||
|
||||
At the moment, the expected user login process is as follows:
|
||||
|
||||
|
||||
First Launch
|
||||
------------
|
||||
|
||||
When you first visit the app, it will not have any user accounts so
|
||||
you will be shown a form to create one.
|
||||
|
||||
The username should ideally match your main (daily driver) username
|
||||
within farmOS. The password you give can be anything though, does not
|
||||
need to (and perhaps should not) match farmOS.
|
||||
|
||||
This account will belong to the Administrator role within WuttaFarm,
|
||||
which means it can "become root" (same concept as ``sudo`` basically).
|
||||
|
||||
Once the account is created you will be shown the normal login page.
|
||||
Go ahead and login with this account using the username and password
|
||||
you gave it. But then you should logout again, for the next step.
|
||||
|
||||
|
||||
OAuth2
|
||||
------
|
||||
|
||||
The assumption (for now) is that users will login via farmOS / OAuth2
|
||||
for normal operations. Doing so will embed the access token within
|
||||
the WuttaFarm app user session, which means the user can actually
|
||||
browse farmOS data within the WuttaFarm views.
|
||||
|
||||
.. note::
|
||||
|
||||
If you login to WuttaFarm directly with username/password, then
|
||||
your user session will not have a farmOS access token and so the
|
||||
farmOS data views in WuttaFarm will not work (i.e. anything under
|
||||
the **farmOS** menu).
|
||||
|
||||
(However this does not affect the "native" data views for
|
||||
WuttaFarm. Users can see data which was already imported from
|
||||
farmOS without an access token - if they have appropriate
|
||||
permissions in WuttaFarm.)
|
||||
|
||||
On the login page, click the "Login via farmOS / OAuth2" button. This
|
||||
will initiate the OAuth2 workflow, at which point you may be asked to
|
||||
login to farmOS (if you're not already) and if you wish to grant
|
||||
access to the 3rd party app (WuttaFarm; if you didn't already).
|
||||
|
||||
If all goes well you should be back in WuttaFarm, logged in as the
|
||||
same username you have in farmOS.
|
||||
|
||||
Note that your first admin user in WuttaFarm ideally *should* have the
|
||||
same username as farmOS, but regardless when you login via OAuth2, a
|
||||
user account will be automatically created if necessary in WuttaFarm,
|
||||
with that same username.
|
||||
39
docs/narr/cli.rst
Normal file
39
docs/narr/cli.rst
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
========================
|
||||
Command Line Interface
|
||||
========================
|
||||
|
||||
WuttaFarm ships with the following commands.
|
||||
|
||||
For more general info about CLI see
|
||||
:doc:`wuttjamaican:narr/cli/index`.
|
||||
|
||||
|
||||
.. _wuttafarm-install:
|
||||
|
||||
``wuttafarm install``
|
||||
---------------------
|
||||
|
||||
Run the WuttaFarm app installer.
|
||||
|
||||
This will create the :term:`app dir` and initial config files, and
|
||||
create the schema within the :term:`app database`.
|
||||
|
||||
Defined in: :mod:`wuttafarm.cli.install`
|
||||
|
||||
.. program-output:: wuttafarm install --help
|
||||
|
||||
|
||||
.. _wuttafarm-import-farmos:
|
||||
|
||||
``wuttafarm import-farmos``
|
||||
---------------------------
|
||||
|
||||
Import data from the farmOS API into the WuttaFarm :term:`app
|
||||
database`.
|
||||
|
||||
Defined in: :mod:`wuttafarm.cli.import_farmos`
|
||||
|
||||
.. program-output:: wuttafarm import-farmos --help
|
||||
|
||||
|
||||
122
docs/narr/features.rst
Normal file
122
docs/narr/features.rst
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
|
||||
========
|
||||
Features
|
||||
========
|
||||
|
||||
Here is the list of features currently supported:
|
||||
|
||||
* login via farmOS / OAuth2 workflows
|
||||
* Authorization Code workflow is supported
|
||||
* (technically, Password Grant workflow is also supported, for now)
|
||||
|
||||
* view some farmOS data directly
|
||||
* limited data is fetched via farmOS API for several views
|
||||
* performance isn't bad, but data is not very "complete"
|
||||
* more data could be fetched, but not sure this is the best way..?
|
||||
|
||||
* import some data from farmOS
|
||||
* limited data is imported from farmOS API into native app tables
|
||||
* this data is exposed in views, similar to direct farmOS views (above)
|
||||
|
||||
* export some data back to farmOS
|
||||
* limited data is exported back via farmOS API, from native tables
|
||||
* supported tables are auto-synced when a record is created/updated
|
||||
* AnimalType
|
||||
* AnimalAsset
|
||||
* GroupAsset
|
||||
* LandAsset
|
||||
* StructureAsset
|
||||
|
||||
|
||||
How I Use This App
|
||||
------------------
|
||||
|
||||
My production farmOS instance is deployed via Podman container, which
|
||||
I prefer over Docker. (Not that I know much about any of that
|
||||
really.) It has a PostgreSQL database which runs in a separate
|
||||
container.
|
||||
|
||||
My production WuttaFarm instance is installed directly on the same
|
||||
host machine, in a Python virtual environment. PostgreSQL is also
|
||||
installed on the host machine; the app uses that for DB.
|
||||
|
||||
I ran the initial "special" import to establish the user accounts;
|
||||
then I ran the "full" import (farmOS → WuttaFarm). See also
|
||||
:doc:`/narr/install`.
|
||||
|
||||
I configured a cron job to run the full import every night, but in
|
||||
dry-run mode with warnings. This means I will get an email if
|
||||
WuttaFarm is ever out of sync with farmOS.
|
||||
|
||||
With all that in place, I can use WuttaFarm as my "daily driver" to
|
||||
add/edit assets (and soon, logs). Changes I make are immediately
|
||||
synced to farmOS, so as long as the overnight check does not send me
|
||||
an email, I know everything is good.
|
||||
|
||||
|
||||
Roadmap
|
||||
-------
|
||||
|
||||
Here are some things I still have planned so far:
|
||||
|
||||
* finish support for auto-sync, in current asset models
|
||||
* must make "asset parents" editable
|
||||
|
||||
* add more asset models?
|
||||
* i may only add those i need for now, but others can add more
|
||||
|
||||
* flesh out the log model support
|
||||
* add more tables, fields to schema
|
||||
* add/improve import and export
|
||||
* basically this should be as good as the asset model support
|
||||
* although again i may only add those i need for now
|
||||
|
||||
* add custom "quick forms" for assets and logs
|
||||
* again i probably will just add a few (e.g. egg collection)
|
||||
* but this could be an interesting path to go down, we'll see
|
||||
|
||||
* add custom "CSV/file importers"
|
||||
* the framework has some pretty neat tools around this, so..
|
||||
* ..even if i don't need CSV import i'd like to show what's possible
|
||||
|
||||
Notably **off the table** for now are:
|
||||
|
||||
* anything involving maps
|
||||
* file/image attachments
|
||||
|
||||
I will just import "thumbnail" and "large" image URLs from farmOS for
|
||||
each asset for now. Will have to think more on the image/attachment
|
||||
stuff before I'll know if/how to add support in WuttaFarm.
|
||||
|
||||
Maps will wait mostly because I have never done anything involving
|
||||
those (or GIS etc. - if that's even the right term). And anyway the
|
||||
main "use" for this app is probably around data entry, so it may never
|
||||
"need" maps support.
|
||||
|
||||
|
||||
Screenshots
|
||||
-----------
|
||||
|
||||
|
||||
Login Screen
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://wuttaproject.org/images/wuttafarm/screenshot001.png
|
||||
|
||||
|
||||
List All Assets
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://wuttaproject.org/images/wuttafarm/screenshot002.png
|
||||
|
||||
|
||||
View Animal Asset
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://wuttaproject.org/images/wuttafarm/screenshot003.png
|
||||
|
||||
|
||||
Edit Animal Asset
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://wuttaproject.org/images/wuttafarm/screenshot004.png
|
||||
185
docs/narr/install.rst
Normal file
185
docs/narr/install.rst
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
|
||||
==============
|
||||
Installation
|
||||
==============
|
||||
|
||||
For now, these instructions mostly reflect my own dev workflow. It
|
||||
uses a Python virtual environment but no (Docker) containers.
|
||||
|
||||
Eventually it may make sense to add production deployment steps using
|
||||
Docker etc. - but that will wait for now.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
WuttaFarm is designed to run on a (Debian-based) Linux machine; YMMV
|
||||
with others.
|
||||
|
||||
|
||||
farmOS
|
||||
~~~~~~
|
||||
|
||||
First you must have a *production* `farmOS`_ instance running
|
||||
somewhere. For more on that see `Hosting farmOS`_.
|
||||
|
||||
.. _farmOS: https://farmos.org
|
||||
.. _Hosting farmOS: https://farmos.org/hosting/
|
||||
|
||||
This must use HTTPS for the OAuth2 workflows to work correctly. (Not
|
||||
sure but it may also need to be at the root of the domain, i.e. no
|
||||
subpath.)
|
||||
|
||||
|
||||
Database
|
||||
~~~~~~~~
|
||||
|
||||
You also must create a PostgreSQL (or MySQL) database for the
|
||||
WuttaFarm app to use. See also :ref:`wuttjamaican:create-appdb`.
|
||||
|
||||
|
||||
App Setup
|
||||
---------
|
||||
|
||||
The short version:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
python3 -m venv ./venv
|
||||
./venv/bin/pip install WuttaFarm
|
||||
./venv/bin/wuttafarm install
|
||||
|
||||
The app installer (last command above) will prompt you for DB
|
||||
credentials, and the farmOS URL.
|
||||
|
||||
One of the questions is about data versioning with
|
||||
:doc:`wutta-continuum:index`. You should probaby enable that even
|
||||
though as of writing the default is disabled. It adds "revision
|
||||
history" for most types of records in the WuttaFarm app DB.
|
||||
|
||||
When the installer completes it will output a command you can then use
|
||||
to run the web app. Do that and you can then view the app in a
|
||||
browser at http://localhost:9080
|
||||
|
||||
|
||||
OAuth2 Setup
|
||||
------------
|
||||
|
||||
At this point the web app should be ready for OAuth2 login; however
|
||||
the OAuth2 provider in farmOS needs some more config before it will
|
||||
work.
|
||||
|
||||
WuttaFarm uses the default ``farm`` consumer, so the only thing you
|
||||
should have to do here is edit that to add your redirect URL. This
|
||||
will vary based on your WuttaFarm site name, e.g.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
https://wuttafarm.example.com/farmos/oauth/callback
|
||||
|
||||
With that in place you should be able to login via OAuth2; see also
|
||||
:doc:`/narr/auth`.
|
||||
|
||||
However while you're there, you should also do some setup for the sake
|
||||
of the farmOS → WuttaFarm data import. This import will also use the
|
||||
farmOS API and therefore also needs an oauth2 access token; however it
|
||||
uses the Client Credentials workflow instead of the Authorization Code
|
||||
workflow. Therefore you must create a new *user* and a new OAuth2
|
||||
*consumer* for it.
|
||||
|
||||
First add a new user in farmOS, named ``wuttafarm``. It should
|
||||
probably be given the Manager role, since WuttaFarm will eventually
|
||||
also support "exporting" data back to farmOS.
|
||||
|
||||
Then add a new OAuth2 consumer (aka. client) with these attributes:
|
||||
|
||||
* **Label:** WuttaFarm
|
||||
* **Client ID:** wuttafarm
|
||||
* **New Secret:** (put something in here, to be used as client secret)
|
||||
* **Grant Types:** Client Credentials, Refresh Token (maybe more?)
|
||||
* **User:** wuttafarm
|
||||
* **3rd Party?** yes
|
||||
* **Confidential?** yes
|
||||
* **Access Token Expiration Time:** maybe set to 3600? or maybe 300
|
||||
default is okay?
|
||||
* **Allowed Origins:** put your oauth callback URL here (same as for
|
||||
default ``farm`` consumer)
|
||||
|
||||
WuttaFarm also needs to know the client secret for sake of running the
|
||||
import; so add this to your ``app/wutta.conf`` file. Of course
|
||||
replace the value with whatever client secret you gave the new
|
||||
consumer:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[farmos.oauth2]
|
||||
importing.client_secret = you_cant_guess_me
|
||||
|
||||
|
||||
Email Setup
|
||||
-----------
|
||||
|
||||
WuttaFarm can send emails of various kinds; of note are:
|
||||
|
||||
* when user submits Feedback via button in top right of screen
|
||||
* importer diff warning for farmOS → WuttaFarm
|
||||
|
||||
That last one is optional, triggered via the ``-W`` flag in the
|
||||
importer command line.
|
||||
|
||||
Anyway the app basically assumes there is a Postfix or similar mail
|
||||
server running on "localhost" which it can use as the SMTP server, and
|
||||
which is in turn responsible for "really" sending the email out via
|
||||
some configured relay. This has always worked very well for me since
|
||||
I tend to want to have email working for other reasons on each Linux
|
||||
server I maintain. (And since I have not traditionally used Docker
|
||||
and/or containers.)
|
||||
|
||||
So if you need something else, touch base and we'll figure something
|
||||
out. But assuming localhost is okay to use:
|
||||
|
||||
In the web app menu, see Admin -> App Info and then click Configure.
|
||||
Check the box to enable email and plug in the default sender and
|
||||
recipient (which should be the admin responsible for the app). I
|
||||
often create an alias so I can use e.g. wuttafarm@edbob.org as
|
||||
sender - aliased back to myself in case it generates bounces so I can
|
||||
see them.
|
||||
|
||||
From there you can also see Admin -> Email Settings in the menu; this
|
||||
lets you control and preview each type of email separately.
|
||||
|
||||
|
||||
Import Data from farmOS
|
||||
-----------------------
|
||||
|
||||
You must have done all the OAuth2 setup (previous section) before the
|
||||
import will work.
|
||||
|
||||
But now that you did all that, importing should be quick and easy.
|
||||
|
||||
The very first import will be limited and "special" to account for any
|
||||
users which were already created in WuttaFarm. This command will
|
||||
ensure WuttaFarm gets *all* user accounts and each is appropriately
|
||||
mapped to the farmOS account:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
./venv/bin/wuttafarm --runas farmos import-farmos User --key username
|
||||
|
||||
Note also the ``--runas farmos`` arg which helps the WuttaFarm data
|
||||
versioning know "who" is responsible for the changes. We use a
|
||||
dedicated ``farmos`` user account in WuttaFarm, to represent the
|
||||
farmOS system as a whole.
|
||||
|
||||
From now on you can run the "full" import normally:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
./venv/bin/wuttafarm --runas farmos import-farmos
|
||||
|
||||
And it can sometimes be helpful to "double-check" in order to make
|
||||
sure all data is fully synced:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
./venv/bin/wuttafarm --runas farmos import-farmos --delete --dry-run -W
|
||||
|
|
@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|||
|
||||
[project]
|
||||
name = "WuttaFarm"
|
||||
version = "0.1.0"
|
||||
version = "0.7.0"
|
||||
description = "Web app to integrate with and extend farmOS"
|
||||
readme = "README.md"
|
||||
authors = [
|
||||
|
|
@ -31,28 +31,42 @@ license = {text = "GNU General Public License v3"}
|
|||
dependencies = [
|
||||
"farmOS",
|
||||
"psycopg2",
|
||||
"WuttaWeb[continuum]",
|
||||
"pyramid_exclog",
|
||||
"uvicorn[standard]",
|
||||
"WuttaSync",
|
||||
"WuttaWeb[continuum]>=0.29.0",
|
||||
]
|
||||
|
||||
|
||||
[project.optional-dependencies]
|
||||
docs = ["Sphinx", "furo", "sphinxcontrib-programoutput"]
|
||||
|
||||
|
||||
[project.scripts]
|
||||
"wuttafarm" = "wuttafarm.cli:wuttafarm_typer"
|
||||
|
||||
[project.entry-points."paste.app_factory"]
|
||||
"main" = "wuttafarm.web.app:main"
|
||||
|
||||
[project.entry-points."wutta.app.providers"]
|
||||
wuttafarm = "wuttafarm.app:WuttaFarmAppProvider"
|
||||
|
||||
[project.entry-points."wutta.config.extensions"]
|
||||
"wuttafarm" = "wuttafarm.config:WuttaFarmConfig"
|
||||
|
||||
[project.entry-points."wutta.web.menus"]
|
||||
"wuttafarm" = "wuttafarm.web.menus:WuttaFarmMenuHandler"
|
||||
|
||||
[project.entry-points."wuttasync.importing"]
|
||||
"export.to_farmos.from_wuttafarm" = "wuttafarm.farmos.importing.wuttafarm:FromWuttaFarmToFarmOS"
|
||||
"import.to_wuttafarm.from_farmos" = "wuttafarm.importing.farmos:FromFarmOSToWuttaFarm"
|
||||
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://forgejo.wuttaproject.org/lance/wuttafarm"
|
||||
Repository = "https://forgejo.wuttaproject.org/lance/wuttafarm"
|
||||
Issues = "https://forgejo.wuttaproject.org/lance/wuttafarm/issues"
|
||||
Changelog = "https://forgejo.wuttaproject.org/lance/wuttafarm/src/branch/master/CHANGELOG.md"
|
||||
Homepage = "https://forgejo.wuttaproject.org/wutta/wuttafarm"
|
||||
Repository = "https://forgejo.wuttaproject.org/wutta/wuttafarm"
|
||||
Issues = "https://forgejo.wuttaproject.org/wutta/wuttafarm/issues"
|
||||
Changelog = "https://forgejo.wuttaproject.org/wutta/wuttafarm/src/branch/master/CHANGELOG.md"
|
||||
|
||||
|
||||
[tool.commitizen]
|
||||
|
|
@ -62,3 +76,8 @@ update_changelog_on_bump = true
|
|||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["src/wuttafarm"]
|
||||
|
||||
[tool.hatch.build.targets.sdist]
|
||||
exclude = [
|
||||
"style/node_modules/",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -31,7 +31,25 @@ class WuttaFarmAppHandler(base.AppHandler):
|
|||
Custom :term:`app handler` for WuttaFarm.
|
||||
"""
|
||||
|
||||
display_format_datetime = "%a, %m/%d/%Y - %H:%M"
|
||||
|
||||
default_auth_handler_spec = "wuttafarm.auth:WuttaFarmAuthHandler"
|
||||
default_install_handler_spec = "wuttafarm.install:WuttaFarmInstallHandler"
|
||||
|
||||
def get_asset_handler(self):
|
||||
"""
|
||||
Get the configured asset handler.
|
||||
|
||||
:rtype: :class:`~wuttafarm.assets.AssetHandler`
|
||||
"""
|
||||
if "asset" not in self.handlers:
|
||||
spec = self.config.get(
|
||||
f"{self.appname}.asset_handler",
|
||||
default="wuttafarm.assets:AssetHandler",
|
||||
)
|
||||
factory = self.load_object(spec)
|
||||
self.handlers["asset"] = factory(self.config)
|
||||
return self.handlers["asset"]
|
||||
|
||||
def get_farmos_handler(self):
|
||||
"""
|
||||
|
|
@ -42,16 +60,167 @@ class WuttaFarmAppHandler(base.AppHandler):
|
|||
if "farmos" not in self.handlers:
|
||||
spec = self.config.get(
|
||||
f"{self.appname}.farmos_handler",
|
||||
default="wuttafarm.farmos:FarmOSHandler",
|
||||
default="wuttafarm.farmos.handler:FarmOSHandler",
|
||||
)
|
||||
factory = self.load_object(spec)
|
||||
self.handlers["farmos"] = factory(self.config)
|
||||
return self.handlers["farmos"]
|
||||
|
||||
def get_farmos_integration_mode(self):
|
||||
"""
|
||||
Returns the integration mode for farmOS, i.e. to control the
|
||||
app's behavior regarding that.
|
||||
"""
|
||||
enum = self.enum
|
||||
return self.config.get(
|
||||
f"{self.appname}.farmos_integration_mode",
|
||||
default=enum.FARMOS_INTEGRATION_MODE_WRAPPER,
|
||||
)
|
||||
|
||||
def is_farmos_mirror(self):
|
||||
"""
|
||||
Returns ``True`` if the app is configured in "mirror"
|
||||
integration mode with regard to farmOS.
|
||||
"""
|
||||
enum = self.enum
|
||||
mode = self.get_farmos_integration_mode()
|
||||
return mode == enum.FARMOS_INTEGRATION_MODE_MIRROR
|
||||
|
||||
def is_farmos_wrapper(self):
|
||||
"""
|
||||
Returns ``True`` if the app is configured in "wrapper"
|
||||
integration mode with regard to farmOS.
|
||||
"""
|
||||
enum = self.enum
|
||||
mode = self.get_farmos_integration_mode()
|
||||
return mode == enum.FARMOS_INTEGRATION_MODE_WRAPPER
|
||||
|
||||
def is_standalone(self):
|
||||
"""
|
||||
Returns ``True`` if the app is configured in "standalone" mode
|
||||
with regard to farmOS.
|
||||
"""
|
||||
enum = self.enum
|
||||
mode = self.get_farmos_integration_mode()
|
||||
return mode == enum.FARMOS_INTEGRATION_MODE_NONE
|
||||
|
||||
def get_farmos_url(self, *args, **kwargs):
|
||||
"""
|
||||
Get a farmOS URL. This is a convenience wrapper around
|
||||
:meth:`~wuttafarm.farmos.FarmOSHandler.get_farmos_url()`.
|
||||
:meth:`~wuttafarm.farmos.handler.FarmOSHandler.get_farmos_url()`.
|
||||
"""
|
||||
handler = self.get_farmos_handler()
|
||||
return handler.get_farmos_url(*args, **kwargs)
|
||||
|
||||
def get_farmos_client(self, *args, **kwargs):
|
||||
"""
|
||||
Get a farmOS client. This is a convenience wrapper around
|
||||
:meth:`~wuttafarm.farmos.handler.FarmOSHandler.get_farmos_client()`.
|
||||
"""
|
||||
handler = self.get_farmos_handler()
|
||||
return handler.get_farmos_client(*args, **kwargs)
|
||||
|
||||
def is_farmos_3x(self, *args, **kwargs):
|
||||
"""
|
||||
Check if the farmOS version is 3.x. This is a convenience
|
||||
wrapper around
|
||||
:meth:`~wuttafarm.farmos.handler.FarmOSHandler.is_farmos_3x()`.
|
||||
"""
|
||||
handler = self.get_farmos_handler()
|
||||
return handler.is_farmos_3x(*args, **kwargs)
|
||||
|
||||
def is_farmos_4x(self, *args, **kwargs):
|
||||
"""
|
||||
Check if the farmOS version is 4.x. This is a convenience
|
||||
wrapper around
|
||||
:meth:`~wuttafarm.farmos.handler.FarmOSHandler.is_farmos_4x()`.
|
||||
"""
|
||||
handler = self.get_farmos_handler()
|
||||
return handler.is_farmos_4x(*args, **kwargs)
|
||||
|
||||
def get_normalizer(self, farmos_client=None):
|
||||
"""
|
||||
Get the configured farmOS integration handler.
|
||||
|
||||
:rtype: :class:`~wuttafarm.farmos.FarmOSHandler`
|
||||
"""
|
||||
spec = self.config.get(
|
||||
f"{self.appname}.normalizer_spec",
|
||||
default="wuttafarm.normal:Normalizer",
|
||||
)
|
||||
factory = self.load_object(spec)
|
||||
return factory(self.config, farmos_client)
|
||||
|
||||
def auto_sync_to_farmos(self, obj, model_name=None, client=None, require=True):
|
||||
"""
|
||||
Export the given object to farmOS, using configured handler.
|
||||
|
||||
This should ensure the given object is also *updated* with the
|
||||
farmOS UUID and Drupal ID, when new record is created in
|
||||
farmOS.
|
||||
|
||||
:param obj: Any data object in WuttaFarm, e.g. AnimalAsset
|
||||
instance.
|
||||
|
||||
:param client: Existing farmOS API client to use. If not
|
||||
specified, a new one will be instantiated.
|
||||
|
||||
:param require: If true, this will *require* the export
|
||||
handler to support objects of the given type. If false,
|
||||
then nothing will happen / export is silently skipped when
|
||||
there is no such exporter.
|
||||
"""
|
||||
handler = self.app.get_import_handler("export.to_farmos.from_wuttafarm")
|
||||
|
||||
if not model_name:
|
||||
model_name = type(obj).__name__
|
||||
if model_name not in handler.importers:
|
||||
if require:
|
||||
raise ValueError(f"no exporter found for {model_name}")
|
||||
return
|
||||
|
||||
# nb. begin txn to establish the API client
|
||||
handler.begin_target_transaction(client)
|
||||
importer = handler.get_importer(model_name, caches_target=False)
|
||||
normal = importer.normalize_source_object(obj)
|
||||
importer.process_data(source_data=[normal])
|
||||
|
||||
def auto_sync_from_farmos(self, obj, model_name, client=None, require=True):
|
||||
"""
|
||||
Import the given object from farmOS, using configured handler.
|
||||
|
||||
:param obj: Any data record from farmOS.
|
||||
|
||||
:param model_name': Model name for the importer to use,
|
||||
e.g. ``"AnimalAsset"``.
|
||||
|
||||
:param client: Existing farmOS API client to use. If not
|
||||
specified, a new one will be instantiated.
|
||||
|
||||
:param require: If true, this will *require* the import
|
||||
handler to support objects of the given type. If false,
|
||||
then nothing will happen / import is silently skipped when
|
||||
there is no such importer.
|
||||
"""
|
||||
handler = self.app.get_import_handler("import.to_wuttafarm.from_farmos")
|
||||
|
||||
if model_name not in handler.importers:
|
||||
if require:
|
||||
raise ValueError(f"no importer found for {model_name}")
|
||||
return
|
||||
|
||||
# nb. begin txn to establish the API client
|
||||
handler.begin_source_transaction(client)
|
||||
with self.short_session(commit=True) as session:
|
||||
handler.target_session = session
|
||||
importer = handler.get_importer(model_name, caches_target=False)
|
||||
normal = importer.normalize_source_object(obj)
|
||||
importer.process_data(source_data=[normal])
|
||||
|
||||
|
||||
class WuttaFarmAppProvider(base.AppProvider):
|
||||
"""
|
||||
The :term:`app provider` for WuttaFarm.
|
||||
"""
|
||||
|
||||
email_modules = ["wuttafarm.emails"]
|
||||
|
|
|
|||
65
src/wuttafarm/assets.py
Normal file
65
src/wuttafarm/assets.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# WuttaFarm --Web app to integrate with and extend farmOS
|
||||
# Copyright © 2026 Lance Edgar
|
||||
#
|
||||
# This file is part of WuttaFarm.
|
||||
#
|
||||
# WuttaFarm is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# WuttaFarm is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# WuttaFarm. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
Asset handler
|
||||
"""
|
||||
|
||||
from wuttjamaican.app import GenericHandler
|
||||
|
||||
|
||||
class AssetHandler(GenericHandler):
|
||||
"""
|
||||
Base class and default implementation for the asset
|
||||
:term:`handler`.
|
||||
"""
|
||||
|
||||
def get_groups(self, asset):
|
||||
model = self.app.model
|
||||
session = self.app.get_session(asset)
|
||||
|
||||
grplog = (
|
||||
session.query(model.Log)
|
||||
.join(model.LogAsset)
|
||||
.filter(model.LogAsset.asset == asset)
|
||||
.filter(model.Log.is_group_assignment == True)
|
||||
.order_by(model.Log.timestamp.desc())
|
||||
.first()
|
||||
)
|
||||
if grplog:
|
||||
return grplog.groups
|
||||
return []
|
||||
|
||||
def get_locations(self, asset):
|
||||
model = self.app.model
|
||||
session = self.app.get_session(asset)
|
||||
|
||||
loclog = (
|
||||
session.query(model.Log)
|
||||
.join(model.LogAsset)
|
||||
.filter(model.LogAsset.asset == asset)
|
||||
.filter(model.Log.is_movement == True)
|
||||
.order_by(model.Log.timestamp.desc())
|
||||
.first()
|
||||
)
|
||||
if loclog:
|
||||
return loclog.locations
|
||||
return []
|
||||
|
|
@ -25,7 +25,6 @@ Auth handler for use with farmOS
|
|||
|
||||
from uuid import UUID
|
||||
|
||||
from farmOS import farmOS
|
||||
from oauthlib.oauth2.rfc6749.errors import InvalidGrantError
|
||||
from sqlalchemy import orm
|
||||
|
||||
|
|
@ -89,8 +88,7 @@ class WuttaFarmAuthHandler(AuthHandler):
|
|||
return None
|
||||
|
||||
def get_farmos_oauth2_token(self, username, password):
|
||||
url = self.app.get_farmos_url()
|
||||
client = farmOS(url)
|
||||
client = self.app.get_farmos_client()
|
||||
try:
|
||||
return client.authorize(username=username, password=password)
|
||||
except InvalidGrantError:
|
||||
|
|
|
|||
31
src/wuttafarm/cli/__init__.py
Normal file
31
src/wuttafarm/cli/__init__.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# WuttaFarm --Web app to integrate with and extend farmOS
|
||||
# Copyright © 2026 Lance Edgar
|
||||
#
|
||||
# This file is part of WuttaFarm.
|
||||
#
|
||||
# WuttaFarm is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# WuttaFarm is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# WuttaFarm. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
WuttaFarm CLI
|
||||
"""
|
||||
|
||||
from .base import wuttafarm_typer
|
||||
|
||||
# nb. must bring in all modules for discovery to work
|
||||
from . import export_farmos
|
||||
from . import import_farmos
|
||||
from . import install
|
||||
31
src/wuttafarm/cli/base.py
Normal file
31
src/wuttafarm/cli/base.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# WuttaFarm --Web app to integrate with and extend farmOS
|
||||
# Copyright © 2026 Lance Edgar
|
||||
#
|
||||
# This file is part of WuttaFarm.
|
||||
#
|
||||
# WuttaFarm is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# WuttaFarm is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# WuttaFarm. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
WuttaFarm CLI - base Typer instance
|
||||
"""
|
||||
|
||||
from wuttjamaican.cli import make_typer
|
||||
|
||||
|
||||
wuttafarm_typer = make_typer(
|
||||
name="wuttafarm", help="WuttaFarm -- Web app to integrate with and extend farmOS"
|
||||
)
|
||||
41
src/wuttafarm/cli/export_farmos.py
Normal file
41
src/wuttafarm/cli/export_farmos.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# WuttaFarm --Web app to integrate with and extend farmOS
|
||||
# Copyright © 2026 Lance Edgar
|
||||
#
|
||||
# This file is part of WuttaFarm.
|
||||
#
|
||||
# WuttaFarm is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# WuttaFarm is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# WuttaFarm. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
See also: :ref:`wuttafarm-export-farmos`
|
||||
"""
|
||||
|
||||
import typer
|
||||
|
||||
from wuttasync.cli import import_command, ImportCommandHandler
|
||||
|
||||
from wuttafarm.cli import wuttafarm_typer
|
||||
|
||||
|
||||
@wuttafarm_typer.command()
|
||||
@import_command
|
||||
def export_farmos(ctx: typer.Context, **kwargs):
|
||||
"""
|
||||
Export data from WuttaFarm to farmOS API
|
||||
"""
|
||||
config = ctx.parent.wutta_config
|
||||
handler = ImportCommandHandler(config, key="export.to_farmos.from_wuttafarm")
|
||||
handler.run(ctx)
|
||||
41
src/wuttafarm/cli/import_farmos.py
Normal file
41
src/wuttafarm/cli/import_farmos.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# WuttaFarm --Web app to integrate with and extend farmOS
|
||||
# Copyright © 2026 Lance Edgar
|
||||
#
|
||||
# This file is part of WuttaFarm.
|
||||
#
|
||||
# WuttaFarm is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# WuttaFarm is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# WuttaFarm. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
See also: :ref:`wuttafarm-import-farmos`
|
||||
"""
|
||||
|
||||
import typer
|
||||
|
||||
from wuttasync.cli import import_command, ImportCommandHandler
|
||||
|
||||
from wuttafarm.cli import wuttafarm_typer
|
||||
|
||||
|
||||
@wuttafarm_typer.command()
|
||||
@import_command
|
||||
def import_farmos(ctx: typer.Context, **kwargs):
|
||||
"""
|
||||
Import data from farmOS API to WuttaFarm
|
||||
"""
|
||||
config = ctx.parent.wutta_config
|
||||
handler = ImportCommandHandler(config, key="import.to_wuttafarm.from_farmos")
|
||||
handler.run(ctx)
|
||||
|
|
@ -25,12 +25,7 @@ WuttaFarm CLI
|
|||
|
||||
import typer
|
||||
|
||||
from wuttjamaican.cli import make_typer
|
||||
|
||||
|
||||
wuttafarm_typer = make_typer(
|
||||
name="wuttafarm", help="WuttaFarm -- Web app to integrate with and extend farmOS"
|
||||
)
|
||||
from wuttafarm.cli import wuttafarm_typer
|
||||
|
||||
|
||||
@wuttafarm_typer.command()
|
||||
|
|
@ -23,6 +23,8 @@
|
|||
WuttaFarm config extensions
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from wuttjamaican.conf import WuttaConfigExtension
|
||||
|
||||
|
||||
|
|
@ -39,19 +41,26 @@ class WuttaFarmConfig(WuttaConfigExtension):
|
|||
config.setdefault(f"{config.appname}.app_title", "WuttaFarm")
|
||||
config.setdefault(f"{config.appname}.app_dist", "WuttaFarm")
|
||||
|
||||
# app model
|
||||
# app model/enum
|
||||
config.setdefault(f"{config.appname}.model_spec", "wuttafarm.db.model")
|
||||
config.setdefault(f"{config.appname}.enum_spec", "wuttafarm.enum")
|
||||
|
||||
# app handler
|
||||
config.setdefault(
|
||||
f"{config.appname}.app.handler", "wuttafarm.app:WuttaFarmAppHandler"
|
||||
)
|
||||
|
||||
# web app menu
|
||||
# web app stuff
|
||||
config.setdefault(
|
||||
f"{config.appname}.web.menus.handler.spec",
|
||||
f"{config.appname}.web.menus.handler.default_spec",
|
||||
"wuttafarm.web.menus:WuttaFarmMenuHandler",
|
||||
)
|
||||
config.setdefault("wuttaweb.grids.default_pagesize", "50")
|
||||
|
||||
# web app libcache
|
||||
# config.setdefault('wuttaweb.static_libcache.module', 'wuttafarm.web.static')
|
||||
|
||||
# maybe override cert validation for requests lib.
|
||||
# nb. this is "global" and not "specific" to the farmos API requests!
|
||||
if bundle := config.get(f"{config.appname}.requests_ca_bundle"):
|
||||
os.environ.setdefault("REQUESTS_CA_BUNDLE", bundle)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
"""add Log.is_movement
|
||||
|
||||
Revision ID: 0771322957bd
|
||||
Revises: 12de43facb95
|
||||
Create Date: 2026-03-02 20:21:03.889847
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "0771322957bd"
|
||||
down_revision: Union[str, None] = "12de43facb95"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log
|
||||
op.add_column("log", sa.Column("is_movement", sa.Boolean(), nullable=True))
|
||||
op.add_column(
|
||||
"log_version",
|
||||
sa.Column("is_movement", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log
|
||||
op.drop_column("log_version", "is_movement")
|
||||
op.drop_column("log", "is_movement")
|
||||
|
|
@ -0,0 +1,596 @@
|
|||
"""add Plant Assets and more Logs
|
||||
|
||||
Revision ID: 11e0e46f48a6
|
||||
Revises: dd6351e69233
|
||||
Create Date: 2026-02-18 18:11:46.536930
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "11e0e46f48a6"
|
||||
down_revision: Union[str, None] = "dd6351e69233"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# plant_type
|
||||
op.create_table(
|
||||
"plant_type",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("description", sa.String(length=255), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_plant_type")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_plant_type_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_plant_type_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_plant_type_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"plant_type_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"description", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_plant_type_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_plant_type_version_end_transaction_id"),
|
||||
"plant_type_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_plant_type_version_operation_type"),
|
||||
"plant_type_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_plant_type_version_pk_transaction_id",
|
||||
"plant_type_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_plant_type_version_pk_validity",
|
||||
"plant_type_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_plant_type_version_transaction_id"),
|
||||
"plant_type_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# asset_plant
|
||||
op.create_table(
|
||||
"asset_plant",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["asset.uuid"], name=op.f("fk_asset_plant_uuid_asset")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_plant")),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_plant_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_plant_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_plant_version_end_transaction_id"),
|
||||
"asset_plant_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_plant_version_operation_type"),
|
||||
"asset_plant_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_plant_version_pk_transaction_id",
|
||||
"asset_plant_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_plant_version_pk_validity",
|
||||
"asset_plant_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_plant_version_transaction_id"),
|
||||
"asset_plant_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# asset_plant_plant_type
|
||||
op.create_table(
|
||||
"asset_plant_plant_type",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("plant_asset_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("plant_type_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["plant_asset_uuid"],
|
||||
["asset_plant.uuid"],
|
||||
name=op.f("fk_asset_plant_plant_type_plant_asset_uuid_asset_plant"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["plant_type_uuid"],
|
||||
["plant_type.uuid"],
|
||||
name=op.f("fk_asset_plant_plant_type_plant_type_uuid_plant_type"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_plant_plant_type")),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_plant_plant_type_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"plant_asset_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"plant_type_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_plant_plant_type_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_plant_plant_type_version_end_transaction_id"),
|
||||
"asset_plant_plant_type_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_plant_plant_type_version_operation_type"),
|
||||
"asset_plant_plant_type_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_plant_plant_type_version_pk_transaction_id",
|
||||
"asset_plant_plant_type_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_plant_plant_type_version_pk_validity",
|
||||
"asset_plant_plant_type_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_plant_plant_type_version_transaction_id"),
|
||||
"asset_plant_plant_type_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# log_asset
|
||||
op.create_table(
|
||||
"log_asset",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("log_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("asset_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["asset_uuid"], ["asset.uuid"], name=op.f("fk_log_asset_asset_uuid_asset")
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["log_uuid"], ["log.uuid"], name=op.f("fk_log_asset_log_uuid_log")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_asset")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_asset_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"log_uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"asset_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_asset_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_asset_version_end_transaction_id"),
|
||||
"log_asset_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_asset_version_operation_type"),
|
||||
"log_asset_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_asset_version_pk_transaction_id",
|
||||
"log_asset_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_asset_version_pk_validity",
|
||||
"log_asset_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_asset_version_transaction_id"),
|
||||
"log_asset_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# log_harvest
|
||||
op.create_table(
|
||||
"log_harvest",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["log.uuid"], name=op.f("fk_log_harvest_uuid_log")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_harvest")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_harvest_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_harvest_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_harvest_version_end_transaction_id"),
|
||||
"log_harvest_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_harvest_version_operation_type"),
|
||||
"log_harvest_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_harvest_version_pk_transaction_id",
|
||||
"log_harvest_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_harvest_version_pk_validity",
|
||||
"log_harvest_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_harvest_version_transaction_id"),
|
||||
"log_harvest_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# log_medical
|
||||
op.create_table(
|
||||
"log_medical",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["log.uuid"], name=op.f("fk_log_medical_uuid_log")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_medical")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_medical_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_medical_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_medical_version_end_transaction_id"),
|
||||
"log_medical_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_medical_version_operation_type"),
|
||||
"log_medical_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_medical_version_pk_transaction_id",
|
||||
"log_medical_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_medical_version_pk_validity",
|
||||
"log_medical_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_medical_version_transaction_id"),
|
||||
"log_medical_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# log_observation
|
||||
op.create_table(
|
||||
"log_observation",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["log.uuid"], name=op.f("fk_log_observation_uuid_log")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_observation")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_observation_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_observation_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_observation_version_end_transaction_id"),
|
||||
"log_observation_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_observation_version_operation_type"),
|
||||
"log_observation_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_observation_version_pk_transaction_id",
|
||||
"log_observation_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_observation_version_pk_validity",
|
||||
"log_observation_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_observation_version_transaction_id"),
|
||||
"log_observation_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log_observation
|
||||
op.drop_index(
|
||||
op.f("ix_log_observation_version_transaction_id"),
|
||||
table_name="log_observation_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_observation_version_pk_validity", table_name="log_observation_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_observation_version_pk_transaction_id",
|
||||
table_name="log_observation_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_observation_version_operation_type"),
|
||||
table_name="log_observation_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_observation_version_end_transaction_id"),
|
||||
table_name="log_observation_version",
|
||||
)
|
||||
op.drop_table("log_observation_version")
|
||||
op.drop_table("log_observation")
|
||||
|
||||
# log_medical
|
||||
op.drop_index(
|
||||
op.f("ix_log_medical_version_transaction_id"), table_name="log_medical_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_medical_version_pk_validity", table_name="log_medical_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_medical_version_pk_transaction_id", table_name="log_medical_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_medical_version_operation_type"), table_name="log_medical_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_medical_version_end_transaction_id"),
|
||||
table_name="log_medical_version",
|
||||
)
|
||||
op.drop_table("log_medical_version")
|
||||
op.drop_table("log_medical")
|
||||
|
||||
# log_harvest
|
||||
op.drop_index(
|
||||
op.f("ix_log_harvest_version_transaction_id"), table_name="log_harvest_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_harvest_version_pk_validity", table_name="log_harvest_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_harvest_version_pk_transaction_id", table_name="log_harvest_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_harvest_version_operation_type"), table_name="log_harvest_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_harvest_version_end_transaction_id"),
|
||||
table_name="log_harvest_version",
|
||||
)
|
||||
op.drop_table("log_harvest_version")
|
||||
op.drop_table("log_harvest")
|
||||
|
||||
# log_asset
|
||||
op.drop_index(
|
||||
op.f("ix_log_asset_version_transaction_id"), table_name="log_asset_version"
|
||||
)
|
||||
op.drop_index("ix_log_asset_version_pk_validity", table_name="log_asset_version")
|
||||
op.drop_index(
|
||||
"ix_log_asset_version_pk_transaction_id", table_name="log_asset_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_asset_version_operation_type"), table_name="log_asset_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_asset_version_end_transaction_id"), table_name="log_asset_version"
|
||||
)
|
||||
op.drop_table("log_asset_version")
|
||||
op.drop_table("log_asset")
|
||||
|
||||
# asset_plant_plant_type
|
||||
op.drop_index(
|
||||
op.f("ix_asset_plant_plant_type_version_transaction_id"),
|
||||
table_name="asset_plant_plant_type_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_plant_plant_type_version_pk_validity",
|
||||
table_name="asset_plant_plant_type_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_plant_plant_type_version_pk_transaction_id",
|
||||
table_name="asset_plant_plant_type_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_plant_plant_type_version_operation_type"),
|
||||
table_name="asset_plant_plant_type_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_plant_plant_type_version_end_transaction_id"),
|
||||
table_name="asset_plant_plant_type_version",
|
||||
)
|
||||
op.drop_table("asset_plant_plant_type_version")
|
||||
op.drop_table("asset_plant_plant_type")
|
||||
|
||||
# asset_plant
|
||||
op.drop_index(
|
||||
op.f("ix_asset_plant_version_transaction_id"), table_name="asset_plant_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_plant_version_pk_validity", table_name="asset_plant_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_plant_version_pk_transaction_id", table_name="asset_plant_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_plant_version_operation_type"), table_name="asset_plant_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_plant_version_end_transaction_id"),
|
||||
table_name="asset_plant_version",
|
||||
)
|
||||
op.drop_table("asset_plant_version")
|
||||
op.drop_table("asset_plant")
|
||||
|
||||
# plant_type
|
||||
op.drop_index(
|
||||
op.f("ix_plant_type_version_transaction_id"), table_name="plant_type_version"
|
||||
)
|
||||
op.drop_index("ix_plant_type_version_pk_validity", table_name="plant_type_version")
|
||||
op.drop_index(
|
||||
"ix_plant_type_version_pk_transaction_id", table_name="plant_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_plant_type_version_operation_type"), table_name="plant_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_plant_type_version_end_transaction_id"),
|
||||
table_name="plant_type_version",
|
||||
)
|
||||
op.drop_table("plant_type_version")
|
||||
op.drop_table("plant_type")
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
"""add Asset.owners
|
||||
|
||||
Revision ID: 12de43facb95
|
||||
Revises: 85d4851e8292
|
||||
Create Date: 2026-03-02 19:03:35.511398
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "12de43facb95"
|
||||
down_revision: Union[str, None] = "85d4851e8292"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# asset_owner
|
||||
op.create_table(
|
||||
"asset_owner",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("asset_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("user_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["asset_uuid"], ["asset.uuid"], name=op.f("fk_asset_owner_asset_uuid_asset")
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["user_uuid"], ["user.uuid"], name=op.f("fk_asset_owner_user_uuid_user")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_owner")),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_owner_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"asset_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"user_uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_owner_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_owner_version_end_transaction_id"),
|
||||
"asset_owner_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_owner_version_operation_type"),
|
||||
"asset_owner_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_owner_version_pk_transaction_id",
|
||||
"asset_owner_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_owner_version_pk_validity",
|
||||
"asset_owner_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_owner_version_transaction_id"),
|
||||
"asset_owner_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# asset_owner
|
||||
op.drop_index(
|
||||
op.f("ix_asset_owner_version_transaction_id"), table_name="asset_owner_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_owner_version_pk_validity", table_name="asset_owner_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_owner_version_pk_transaction_id", table_name="asset_owner_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_owner_version_operation_type"), table_name="asset_owner_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_owner_version_end_transaction_id"),
|
||||
table_name="asset_owner_version",
|
||||
)
|
||||
op.drop_table("asset_owner_version")
|
||||
op.drop_table("asset_owner")
|
||||
127
src/wuttafarm/db/alembic/versions/1b2d3224e5dc_add_animals.py
Normal file
127
src/wuttafarm/db/alembic/versions/1b2d3224e5dc_add_animals.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
"""add Animals
|
||||
|
||||
Revision ID: 1b2d3224e5dc
|
||||
Revises: 4dbba8aeb1e5
|
||||
Create Date: 2026-02-13 11:55:19.564221
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "1b2d3224e5dc"
|
||||
down_revision: Union[str, None] = "4dbba8aeb1e5"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# animal
|
||||
op.create_table(
|
||||
"animal",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("animal_type_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("birthdate", sa.DateTime(), nullable=True),
|
||||
sa.Column("sex", sa.String(length=1), nullable=True),
|
||||
sa.Column("is_sterile", sa.Boolean(), nullable=True),
|
||||
sa.Column("active", sa.Boolean(), nullable=False),
|
||||
sa.Column("notes", sa.Text(), nullable=True),
|
||||
sa.Column("image_url", sa.String(length=255), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["animal_type_uuid"],
|
||||
["animal_type.uuid"],
|
||||
name=op.f("fk_animal_animal_type_uuid_animal_type"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_animal")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_animal_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_animal_farmos_uuid")),
|
||||
)
|
||||
op.create_table(
|
||||
"animal_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"animal_type_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("birthdate", sa.DateTime(), autoincrement=False, nullable=True),
|
||||
sa.Column("sex", sa.String(length=1), autoincrement=False, nullable=True),
|
||||
sa.Column("is_sterile", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("active", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.Text(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"image_url", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_animal_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_version_end_transaction_id"),
|
||||
"animal_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_version_operation_type"),
|
||||
"animal_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_animal_version_pk_transaction_id",
|
||||
"animal_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_animal_version_pk_validity",
|
||||
"animal_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_version_transaction_id"),
|
||||
"animal_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# animal
|
||||
op.drop_index(op.f("ix_animal_version_transaction_id"), table_name="animal_version")
|
||||
op.drop_index("ix_animal_version_pk_validity", table_name="animal_version")
|
||||
op.drop_index("ix_animal_version_pk_transaction_id", table_name="animal_version")
|
||||
op.drop_index(op.f("ix_animal_version_operation_type"), table_name="animal_version")
|
||||
op.drop_index(
|
||||
op.f("ix_animal_version_end_transaction_id"), table_name="animal_version"
|
||||
)
|
||||
op.drop_table("animal_version")
|
||||
op.drop_table("animal")
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
"""add Quantity Types
|
||||
|
||||
Revision ID: 1f98d27cabeb
|
||||
Revises: ea88e72a5fa5
|
||||
Create Date: 2026-02-18 21:03:52.245619
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "1f98d27cabeb"
|
||||
down_revision: Union[str, None] = "ea88e72a5fa5"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# quantity_type
|
||||
op.create_table(
|
||||
"quantity_type",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("description", sa.String(length=255), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.String(length=50), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_quantity_type")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_quantity_type_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_quantity_type_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_quantity_type_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"quantity_type_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"description", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"drupal_id", sa.String(length=50), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_quantity_type_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_quantity_type_version_end_transaction_id"),
|
||||
"quantity_type_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_quantity_type_version_operation_type"),
|
||||
"quantity_type_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_quantity_type_version_pk_transaction_id",
|
||||
"quantity_type_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_quantity_type_version_pk_validity",
|
||||
"quantity_type_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_quantity_type_version_transaction_id"),
|
||||
"quantity_type_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# quantity_type
|
||||
op.drop_index(
|
||||
op.f("ix_quantity_type_version_transaction_id"),
|
||||
table_name="quantity_type_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_quantity_type_version_pk_validity", table_name="quantity_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_quantity_type_version_pk_transaction_id", table_name="quantity_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_quantity_type_version_operation_type"),
|
||||
table_name="quantity_type_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_quantity_type_version_end_transaction_id"),
|
||||
table_name="quantity_type_version",
|
||||
)
|
||||
op.drop_table("quantity_type_version")
|
||||
op.drop_table("quantity_type")
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
"""add animal thumbnail url
|
||||
|
||||
Revision ID: 2a49127e974b
|
||||
Revises: 8898184c5c75
|
||||
Create Date: 2026-02-14 19:41:22.039343
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "2a49127e974b"
|
||||
down_revision: Union[str, None] = "8898184c5c75"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# animal
|
||||
op.add_column(
|
||||
"animal", sa.Column("thumbnail_url", sa.String(length=255), nullable=True)
|
||||
)
|
||||
op.add_column(
|
||||
"animal_version",
|
||||
sa.Column(
|
||||
"thumbnail_url", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# animal
|
||||
op.drop_column("animal_version", "thumbnail_url")
|
||||
op.drop_column("animal", "thumbnail_url")
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
"""add Animal Types
|
||||
|
||||
Revision ID: 2b6385d0fa17
|
||||
Revises:
|
||||
Create Date: 2026-02-08 14:55:42.236918
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "2b6385d0fa17"
|
||||
down_revision: Union[str, None] = None
|
||||
branch_labels: Union[str, Sequence[str], None] = ("wuttafarm",)
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# animal_type
|
||||
op.create_table(
|
||||
"animal_type",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("description", sa.String(length=255), nullable=True),
|
||||
sa.Column("changed", sa.DateTime(), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_animal_type")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_animal_type_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_animal_type_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_animal_type_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"animal_type_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"description", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_animal_type_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_type_version_end_transaction_id"),
|
||||
"animal_type_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_type_version_operation_type"),
|
||||
"animal_type_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_animal_type_version_pk_transaction_id",
|
||||
"animal_type_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_animal_type_version_pk_validity",
|
||||
"animal_type_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_type_version_transaction_id"),
|
||||
"animal_type_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# animal_type
|
||||
op.drop_index(
|
||||
op.f("ix_animal_type_version_transaction_id"), table_name="animal_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_animal_type_version_pk_validity", table_name="animal_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_animal_type_version_pk_transaction_id", table_name="animal_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_animal_type_version_operation_type"), table_name="animal_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_animal_type_version_end_transaction_id"),
|
||||
table_name="animal_type_version",
|
||||
)
|
||||
op.drop_table("animal_type_version")
|
||||
op.drop_table("animal_type")
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
"""use shared base for Structure Assets
|
||||
|
||||
Revision ID: 34ec51d80f52
|
||||
Revises: d882682c82f9
|
||||
Create Date: 2026-02-15 13:19:18.814523
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "34ec51d80f52"
|
||||
down_revision: Union[str, None] = "d882682c82f9"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# asset_structure
|
||||
op.create_table(
|
||||
"asset_structure",
|
||||
sa.Column("structure_type_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["structure_type_uuid"],
|
||||
["structure_type.uuid"],
|
||||
name=op.f("fk_asset_structure_structure_type_uuid_structure_type"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["asset.uuid"], name=op.f("fk_asset_structure_uuid_asset")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_structure")),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_structure_version",
|
||||
sa.Column(
|
||||
"structure_type_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_structure_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_structure_version_end_transaction_id"),
|
||||
"asset_structure_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_structure_version_operation_type"),
|
||||
"asset_structure_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_structure_version_pk_transaction_id",
|
||||
"asset_structure_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_structure_version_pk_validity",
|
||||
"asset_structure_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_structure_version_transaction_id"),
|
||||
"asset_structure_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# structure
|
||||
op.drop_index(
|
||||
op.f("ix_structure_version_end_transaction_id"), table_name="structure_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_structure_version_operation_type"), table_name="structure_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_structure_version_pk_transaction_id"), table_name="structure_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_structure_version_pk_validity"), table_name="structure_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_structure_version_transaction_id"), table_name="structure_version"
|
||||
)
|
||||
op.drop_table("structure_version")
|
||||
op.drop_table("structure")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# structure
|
||||
op.create_table(
|
||||
"structure",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
||||
sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column(
|
||||
"structure_type_uuid", sa.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("is_location", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("is_fixed", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"image_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"thumbnail_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["structure_type_uuid"],
|
||||
["structure_type.uuid"],
|
||||
name=op.f("fk_structure_structure_type_uuid_structure_type"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_structure")),
|
||||
sa.UniqueConstraint(
|
||||
"drupal_id",
|
||||
name=op.f("uq_structure_drupal_id"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"farmos_uuid",
|
||||
name=op.f("uq_structure_farmos_uuid"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"name",
|
||||
name=op.f("uq_structure_name"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
)
|
||||
op.create_table(
|
||||
"structure_version",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("structure_type_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("is_location", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("is_fixed", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"image_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column("transaction_id", sa.BIGINT(), autoincrement=False, nullable=False),
|
||||
sa.Column(
|
||||
"end_transaction_id", sa.BIGINT(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("operation_type", sa.SMALLINT(), autoincrement=False, nullable=False),
|
||||
sa.Column(
|
||||
"thumbnail_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_structure_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_version_transaction_id"),
|
||||
"structure_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_version_pk_validity"),
|
||||
"structure_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_version_pk_transaction_id"),
|
||||
"structure_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_version_operation_type"),
|
||||
"structure_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_version_end_transaction_id"),
|
||||
"structure_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# asset_structure
|
||||
op.drop_index(
|
||||
op.f("ix_asset_structure_version_transaction_id"),
|
||||
table_name="asset_structure_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_structure_version_pk_validity", table_name="asset_structure_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_structure_version_pk_transaction_id",
|
||||
table_name="asset_structure_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_structure_version_operation_type"),
|
||||
table_name="asset_structure_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_structure_version_end_transaction_id"),
|
||||
table_name="asset_structure_version",
|
||||
)
|
||||
op.drop_table("asset_structure_version")
|
||||
op.drop_table("asset_structure")
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
"""add LogLocation
|
||||
|
||||
Revision ID: 3bef7d380a38
|
||||
Revises: f3c7e273bfa3
|
||||
Create Date: 2026-02-28 20:41:56.051847
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "3bef7d380a38"
|
||||
down_revision: Union[str, None] = "f3c7e273bfa3"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log_location
|
||||
op.create_table(
|
||||
"log_location",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("log_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("asset_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["asset_uuid"],
|
||||
["asset.uuid"],
|
||||
name=op.f("fk_log_location_asset_uuid_asset"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["log_uuid"], ["log.uuid"], name=op.f("fk_log_location_log_uuid_log")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_location")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_location_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"log_uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"asset_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_location_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_location_version_end_transaction_id"),
|
||||
"log_location_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_location_version_operation_type"),
|
||||
"log_location_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_location_version_pk_transaction_id",
|
||||
"log_location_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_location_version_pk_validity",
|
||||
"log_location_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_location_version_transaction_id"),
|
||||
"log_location_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log_location
|
||||
op.drop_index(
|
||||
op.f("ix_log_location_version_transaction_id"),
|
||||
table_name="log_location_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_location_version_pk_validity", table_name="log_location_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_location_version_pk_transaction_id", table_name="log_location_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_location_version_operation_type"),
|
||||
table_name="log_location_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_location_version_end_transaction_id"),
|
||||
table_name="log_location_version",
|
||||
)
|
||||
op.drop_table("log_location_version")
|
||||
op.drop_table("log_location")
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
"""add Activity Logs
|
||||
|
||||
Revision ID: 3e2ef02bf264
|
||||
Revises: 92b813360b99
|
||||
Create Date: 2026-02-13 14:36:47.191922
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "3e2ef02bf264"
|
||||
down_revision: Union[str, None] = "92b813360b99"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log_activity
|
||||
op.create_table(
|
||||
"log_activity",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("message", sa.String(length=255), nullable=False),
|
||||
sa.Column("timestamp", sa.DateTime(), nullable=False),
|
||||
sa.Column("status", sa.String(length=20), nullable=False),
|
||||
sa.Column("notes", sa.Text(), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_activity")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_log_activity_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_log_activity_farmos_uuid")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_activity_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("message", sa.String(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column("timestamp", sa.DateTime(), autoincrement=False, nullable=True),
|
||||
sa.Column("status", sa.String(length=20), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.Text(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_activity_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_activity_version_end_transaction_id"),
|
||||
"log_activity_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_activity_version_operation_type"),
|
||||
"log_activity_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_activity_version_pk_transaction_id",
|
||||
"log_activity_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_activity_version_pk_validity",
|
||||
"log_activity_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_activity_version_transaction_id"),
|
||||
"log_activity_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log_activity
|
||||
op.drop_index(
|
||||
op.f("ix_log_activity_version_transaction_id"),
|
||||
table_name="log_activity_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_activity_version_pk_validity", table_name="log_activity_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_activity_version_pk_transaction_id", table_name="log_activity_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_activity_version_operation_type"),
|
||||
table_name="log_activity_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_activity_version_end_transaction_id"),
|
||||
table_name="log_activity_version",
|
||||
)
|
||||
op.drop_table("log_activity_version")
|
||||
op.drop_table("log_activity")
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
"""remove unique for animal_type.name
|
||||
|
||||
Revision ID: 45c7718d2ed2
|
||||
Revises: 5b6c87d8cddf
|
||||
Create Date: 2026-02-27 16:53:59.310342
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "45c7718d2ed2"
|
||||
down_revision: Union[str, None] = "5b6c87d8cddf"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# animal_type
|
||||
op.drop_constraint(op.f("uq_animal_type_name"), "animal_type", type_="unique")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# animal_type
|
||||
op.create_unique_constraint(
|
||||
op.f("uq_animal_type_name"),
|
||||
"animal_type",
|
||||
["name"],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
)
|
||||
108
src/wuttafarm/db/alembic/versions/47d0ebd84554_add_logowner.py
Normal file
108
src/wuttafarm/db/alembic/versions/47d0ebd84554_add_logowner.py
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
"""add LogOwner
|
||||
|
||||
Revision ID: 47d0ebd84554
|
||||
Revises: 45c7718d2ed2
|
||||
Create Date: 2026-02-28 19:18:49.122090
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "47d0ebd84554"
|
||||
down_revision: Union[str, None] = "45c7718d2ed2"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log_owner
|
||||
op.create_table(
|
||||
"log_owner",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("log_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("user_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["log_uuid"], ["log.uuid"], name=op.f("fk_log_owner_log_uuid_log")
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["user_uuid"], ["user.uuid"], name=op.f("fk_log_owner_user_uuid_user")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_owner")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_owner_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"log_uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"user_uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_owner_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_owner_version_end_transaction_id"),
|
||||
"log_owner_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_owner_version_operation_type"),
|
||||
"log_owner_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_owner_version_pk_transaction_id",
|
||||
"log_owner_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_owner_version_pk_validity",
|
||||
"log_owner_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_owner_version_transaction_id"),
|
||||
"log_owner_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log_owner
|
||||
op.drop_index(
|
||||
op.f("ix_log_owner_version_transaction_id"), table_name="log_owner_version"
|
||||
)
|
||||
op.drop_index("ix_log_owner_version_pk_validity", table_name="log_owner_version")
|
||||
op.drop_index(
|
||||
"ix_log_owner_version_pk_transaction_id", table_name="log_owner_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_owner_version_operation_type"), table_name="log_owner_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_owner_version_end_transaction_id"), table_name="log_owner_version"
|
||||
)
|
||||
op.drop_table("log_owner_version")
|
||||
op.drop_table("log_owner")
|
||||
132
src/wuttafarm/db/alembic/versions/4dbba8aeb1e5_add_structures.py
Normal file
132
src/wuttafarm/db/alembic/versions/4dbba8aeb1e5_add_structures.py
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
"""add Structures
|
||||
|
||||
Revision ID: 4dbba8aeb1e5
|
||||
Revises: e416b96467fc
|
||||
Create Date: 2026-02-13 10:17:15.179202
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "4dbba8aeb1e5"
|
||||
down_revision: Union[str, None] = "e416b96467fc"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# structure
|
||||
op.create_table(
|
||||
"structure",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("active", sa.Boolean(), nullable=False),
|
||||
sa.Column("structure_type_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("is_location", sa.Boolean(), nullable=False),
|
||||
sa.Column("is_fixed", sa.Boolean(), nullable=False),
|
||||
sa.Column("notes", sa.Text(), nullable=True),
|
||||
sa.Column("image_url", sa.String(length=255), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["structure_type_uuid"],
|
||||
["structure_type.uuid"],
|
||||
name=op.f("fk_structure_structure_type_uuid_structure_type"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_structure")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_structure_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_structure_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_structure_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"structure_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column("active", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"structure_type_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("is_location", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("is_fixed", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.Text(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"image_url", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_structure_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_version_end_transaction_id"),
|
||||
"structure_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_version_operation_type"),
|
||||
"structure_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_structure_version_pk_transaction_id",
|
||||
"structure_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_structure_version_pk_validity",
|
||||
"structure_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_version_transaction_id"),
|
||||
"structure_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# structure
|
||||
op.drop_index(
|
||||
op.f("ix_structure_version_transaction_id"), table_name="structure_version"
|
||||
)
|
||||
op.drop_index("ix_structure_version_pk_validity", table_name="structure_version")
|
||||
op.drop_index(
|
||||
"ix_structure_version_pk_transaction_id", table_name="structure_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_structure_version_operation_type"), table_name="structure_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_structure_version_end_transaction_id"), table_name="structure_version"
|
||||
)
|
||||
op.drop_table("structure_version")
|
||||
op.drop_table("structure")
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
"""add LandAssetParent model
|
||||
|
||||
Revision ID: 554e6168c339
|
||||
Revises: 8cc1565d38e7
|
||||
Create Date: 2026-02-14 20:41:24.859064
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "554e6168c339"
|
||||
down_revision: Union[str, None] = "8cc1565d38e7"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# land_asset_parent
|
||||
op.create_table(
|
||||
"land_asset_parent",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("land_asset_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("parent_asset_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["land_asset_uuid"],
|
||||
["land_asset.uuid"],
|
||||
name=op.f("fk_land_asset_parent_land_asset_uuid_land_asset"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["parent_asset_uuid"],
|
||||
["land_asset.uuid"],
|
||||
name=op.f("fk_land_asset_parent_parent_asset_uuid_land_asset"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_land_asset_parent")),
|
||||
)
|
||||
op.create_table(
|
||||
"land_asset_parent_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"land_asset_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"parent_asset_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_land_asset_parent_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_parent_version_end_transaction_id"),
|
||||
"land_asset_parent_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_parent_version_operation_type"),
|
||||
"land_asset_parent_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_land_asset_parent_version_pk_transaction_id",
|
||||
"land_asset_parent_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_land_asset_parent_version_pk_validity",
|
||||
"land_asset_parent_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_parent_version_transaction_id"),
|
||||
"land_asset_parent_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# land_asset_parent
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_parent_version_transaction_id"),
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_land_asset_parent_version_pk_validity",
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_land_asset_parent_version_pk_transaction_id",
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_parent_version_operation_type"),
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_parent_version_end_transaction_id"),
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_table("land_asset_parent_version")
|
||||
op.drop_table("land_asset_parent")
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
"""add Standard Quantities
|
||||
|
||||
Revision ID: 5b6c87d8cddf
|
||||
Revises: 1f98d27cabeb
|
||||
Create Date: 2026-02-19 15:42:19.691148
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "5b6c87d8cddf"
|
||||
down_revision: Union[str, None] = "1f98d27cabeb"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# measure
|
||||
op.create_table(
|
||||
"measure",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("drupal_id", sa.String(length=20), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_measure")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_measure_drupal_id")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_measure_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"measure_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"drupal_id", sa.String(length=20), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_measure_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_measure_version_end_transaction_id"),
|
||||
"measure_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_measure_version_operation_type"),
|
||||
"measure_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_measure_version_pk_transaction_id",
|
||||
"measure_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_measure_version_pk_validity",
|
||||
"measure_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_measure_version_transaction_id"),
|
||||
"measure_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# quantity
|
||||
op.create_table(
|
||||
"quantity",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("quantity_type_id", sa.String(length=50), nullable=False),
|
||||
sa.Column("measure_id", sa.String(length=20), nullable=False),
|
||||
sa.Column("value_numerator", sa.Integer(), nullable=False),
|
||||
sa.Column("value_denominator", sa.Integer(), nullable=False),
|
||||
sa.Column("units_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("label", sa.String(length=255), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["measure_id"],
|
||||
["measure.drupal_id"],
|
||||
name=op.f("fk_quantity_measure_id_measure"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["quantity_type_id"],
|
||||
["quantity_type.drupal_id"],
|
||||
name=op.f("fk_quantity_quantity_type_id_quantity_type"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["units_uuid"], ["unit.uuid"], name=op.f("fk_quantity_units_uuid_unit")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_quantity")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_quantity_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_quantity_farmos_uuid")),
|
||||
)
|
||||
op.create_table(
|
||||
"quantity_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"quantity_type_id", sa.String(length=50), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"measure_id", sa.String(length=20), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("value_numerator", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"value_denominator", sa.Integer(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"units_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("label", sa.String(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_quantity_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_quantity_version_end_transaction_id"),
|
||||
"quantity_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_quantity_version_operation_type"),
|
||||
"quantity_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_quantity_version_pk_transaction_id",
|
||||
"quantity_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_quantity_version_pk_validity",
|
||||
"quantity_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_quantity_version_transaction_id"),
|
||||
"quantity_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# quantity_standard
|
||||
op.create_table(
|
||||
"quantity_standard",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["quantity.uuid"], name=op.f("fk_quantity_standard_uuid_quantity")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_quantity_standard")),
|
||||
)
|
||||
op.create_table(
|
||||
"quantity_standard_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_quantity_standard_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_quantity_standard_version_end_transaction_id"),
|
||||
"quantity_standard_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_quantity_standard_version_operation_type"),
|
||||
"quantity_standard_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_quantity_standard_version_pk_transaction_id",
|
||||
"quantity_standard_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_quantity_standard_version_pk_validity",
|
||||
"quantity_standard_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_quantity_standard_version_transaction_id"),
|
||||
"quantity_standard_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# quantity_standard
|
||||
op.drop_index(
|
||||
op.f("ix_quantity_standard_version_transaction_id"),
|
||||
table_name="quantity_standard_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_quantity_standard_version_pk_validity",
|
||||
table_name="quantity_standard_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_quantity_standard_version_pk_transaction_id",
|
||||
table_name="quantity_standard_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_quantity_standard_version_operation_type"),
|
||||
table_name="quantity_standard_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_quantity_standard_version_end_transaction_id"),
|
||||
table_name="quantity_standard_version",
|
||||
)
|
||||
op.drop_table("quantity_standard_version")
|
||||
op.drop_table("quantity_standard")
|
||||
|
||||
# quantity
|
||||
op.drop_index(
|
||||
op.f("ix_quantity_version_transaction_id"), table_name="quantity_version"
|
||||
)
|
||||
op.drop_index("ix_quantity_version_pk_validity", table_name="quantity_version")
|
||||
op.drop_index(
|
||||
"ix_quantity_version_pk_transaction_id", table_name="quantity_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_quantity_version_operation_type"), table_name="quantity_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_quantity_version_end_transaction_id"), table_name="quantity_version"
|
||||
)
|
||||
op.drop_table("quantity_version")
|
||||
op.drop_table("quantity")
|
||||
|
||||
# measure
|
||||
op.drop_index(
|
||||
op.f("ix_measure_version_transaction_id"), table_name="measure_version"
|
||||
)
|
||||
op.drop_index("ix_measure_version_pk_validity", table_name="measure_version")
|
||||
op.drop_index("ix_measure_version_pk_transaction_id", table_name="measure_version")
|
||||
op.drop_index(
|
||||
op.f("ix_measure_version_operation_type"), table_name="measure_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_measure_version_end_transaction_id"), table_name="measure_version"
|
||||
)
|
||||
op.drop_table("measure_version")
|
||||
op.drop_table("measure")
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
"""remove unwanted unique constraint
|
||||
|
||||
Revision ID: 5f474125a80e
|
||||
Revises: 0771322957bd
|
||||
Create Date: 2026-03-04 12:03:16.034291
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "5f474125a80e"
|
||||
down_revision: Union[str, None] = "0771322957bd"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# asset_land
|
||||
op.drop_constraint(
|
||||
op.f("uq_asset_land_land_type_uuid"), "asset_land", type_="unique"
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# asset_land
|
||||
op.create_unique_constraint(
|
||||
op.f("uq_asset_land_land_type_uuid"),
|
||||
"asset_land",
|
||||
["land_type_uuid"],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
)
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
"""add WuttaFarmUser
|
||||
|
||||
Revision ID: 6c56bcd1c028
|
||||
Revises: 2b6385d0fa17
|
||||
Create Date: 2026-02-09 20:46:20.995903
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "6c56bcd1c028"
|
||||
down_revision: Union[str, None] = "2b6385d0fa17"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# wuttafarm_user
|
||||
op.create_table(
|
||||
"wuttafarm_user",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["user.uuid"], name=op.f("fk_wuttafarm_user_uuid_user")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_wuttafarm_user")),
|
||||
)
|
||||
op.create_table(
|
||||
"wuttafarm_user_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_wuttafarm_user_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_wuttafarm_user_version_end_transaction_id"),
|
||||
"wuttafarm_user_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_wuttafarm_user_version_operation_type"),
|
||||
"wuttafarm_user_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_wuttafarm_user_version_pk_transaction_id",
|
||||
"wuttafarm_user_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_wuttafarm_user_version_pk_validity",
|
||||
"wuttafarm_user_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_wuttafarm_user_version_transaction_id"),
|
||||
"wuttafarm_user_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# wuttafarm_user
|
||||
op.drop_index(
|
||||
op.f("ix_wuttafarm_user_version_transaction_id"),
|
||||
table_name="wuttafarm_user_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_wuttafarm_user_version_pk_validity", table_name="wuttafarm_user_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_wuttafarm_user_version_pk_transaction_id",
|
||||
table_name="wuttafarm_user_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_wuttafarm_user_version_operation_type"),
|
||||
table_name="wuttafarm_user_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_wuttafarm_user_version_end_transaction_id"),
|
||||
table_name="wuttafarm_user_version",
|
||||
)
|
||||
op.drop_table("wuttafarm_user_version")
|
||||
op.drop_table("wuttafarm_user")
|
||||
111
src/wuttafarm/db/alembic/versions/74d32b4ec210_add_loggroup.py
Normal file
111
src/wuttafarm/db/alembic/versions/74d32b4ec210_add_loggroup.py
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
"""add LogGroup
|
||||
|
||||
Revision ID: 74d32b4ec210
|
||||
Revises: 3bef7d380a38
|
||||
Create Date: 2026-02-28 21:35:24.125784
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "74d32b4ec210"
|
||||
down_revision: Union[str, None] = "3bef7d380a38"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log_group
|
||||
op.create_table(
|
||||
"log_group",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("log_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("asset_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["asset_uuid"], ["asset.uuid"], name=op.f("fk_log_group_asset_uuid_asset")
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["log_uuid"], ["log.uuid"], name=op.f("fk_log_group_log_uuid_log")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_group")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_group_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"log_uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"asset_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_group_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_group_version_end_transaction_id"),
|
||||
"log_group_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_group_version_operation_type"),
|
||||
"log_group_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_group_version_pk_transaction_id",
|
||||
"log_group_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_group_version_pk_validity",
|
||||
"log_group_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_group_version_transaction_id"),
|
||||
"log_group_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log_group
|
||||
op.drop_index(
|
||||
op.f("ix_log_group_version_transaction_id"), table_name="log_group_version"
|
||||
)
|
||||
op.drop_index("ix_log_group_version_pk_validity", table_name="log_group_version")
|
||||
op.drop_index(
|
||||
"ix_log_group_version_pk_transaction_id", table_name="log_group_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_group_version_operation_type"), table_name="log_group_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_group_version_end_transaction_id"), table_name="log_group_version"
|
||||
)
|
||||
op.drop_table("log_group_version")
|
||||
op.drop_table("log_group")
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
"""add produces_eggs via EggMixin
|
||||
|
||||
Revision ID: 82a03f4ef1a4
|
||||
Revises: 11e0e46f48a6
|
||||
Create Date: 2026-02-18 18:45:36.015144
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "82a03f4ef1a4"
|
||||
down_revision: Union[str, None] = "11e0e46f48a6"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# asset_animal
|
||||
op.add_column(
|
||||
"asset_animal", sa.Column("produces_eggs", sa.Boolean(), nullable=True)
|
||||
)
|
||||
op.add_column(
|
||||
"asset_animal_version",
|
||||
sa.Column("produces_eggs", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
)
|
||||
|
||||
# asset_group
|
||||
op.add_column(
|
||||
"asset_group", sa.Column("produces_eggs", sa.Boolean(), nullable=True)
|
||||
)
|
||||
op.add_column(
|
||||
"asset_group_version",
|
||||
sa.Column("produces_eggs", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# asset_group
|
||||
op.drop_column("asset_group_version", "produces_eggs")
|
||||
op.drop_column("asset_group", "produces_eggs")
|
||||
|
||||
# asset_animal
|
||||
op.drop_column("asset_animal_version", "produces_eggs")
|
||||
op.drop_column("asset_animal", "produces_eggs")
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
"""add Log.quick
|
||||
|
||||
Revision ID: 85d4851e8292
|
||||
Revises: d459db991404
|
||||
Create Date: 2026-03-02 18:42:56.070281
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "85d4851e8292"
|
||||
down_revision: Union[str, None] = "d459db991404"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log
|
||||
op.add_column("log", sa.Column("quick", sa.String(length=20), nullable=True))
|
||||
op.add_column(
|
||||
"log_version",
|
||||
sa.Column("quick", sa.String(length=20), autoincrement=False, nullable=True),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log
|
||||
op.drop_column("log_version", "quick")
|
||||
op.drop_column("log", "quick")
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
"""convert active to archived
|
||||
|
||||
Revision ID: 8898184c5c75
|
||||
Revises: 3e2ef02bf264
|
||||
Create Date: 2026-02-14 18:41:23.042951
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "8898184c5c75"
|
||||
down_revision: Union[str, None] = "3e2ef02bf264"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# animal
|
||||
op.alter_column("animal", "active", new_column_name="archived")
|
||||
animal = sa.sql.table(
|
||||
"animal",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("archived"),
|
||||
)
|
||||
cursor = op.get_bind().execute(animal.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
animal.update()
|
||||
.where(animal.c.uuid == row.uuid)
|
||||
.values({"archived": not row.archived})
|
||||
)
|
||||
op.alter_column("animal_version", "active", new_column_name="archived")
|
||||
animal_version = sa.sql.table(
|
||||
"animal_version",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("archived"),
|
||||
)
|
||||
cursor = op.get_bind().execute(animal_version.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
animal_version.update()
|
||||
.where(animal_version.c.uuid == row.uuid)
|
||||
.values({"archived": not row.archived})
|
||||
)
|
||||
|
||||
# group
|
||||
op.alter_column("group", "active", new_column_name="archived")
|
||||
group = sa.sql.table(
|
||||
"group",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("archived"),
|
||||
)
|
||||
cursor = op.get_bind().execute(group.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
group.update()
|
||||
.where(group.c.uuid == row.uuid)
|
||||
.values({"archived": not row.archived})
|
||||
)
|
||||
op.alter_column("group_version", "active", new_column_name="archived")
|
||||
group_version = sa.sql.table(
|
||||
"group_version",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("archived"),
|
||||
)
|
||||
cursor = op.get_bind().execute(group_version.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
group_version.update()
|
||||
.where(group_version.c.uuid == row.uuid)
|
||||
.values({"archived": not row.archived})
|
||||
)
|
||||
|
||||
# land_asset
|
||||
op.alter_column("land_asset", "active", new_column_name="archived")
|
||||
land_asset = sa.sql.table(
|
||||
"land_asset",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("archived"),
|
||||
)
|
||||
cursor = op.get_bind().execute(land_asset.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
land_asset.update()
|
||||
.where(land_asset.c.uuid == row.uuid)
|
||||
.values({"archived": not row.archived})
|
||||
)
|
||||
op.alter_column("land_asset_version", "active", new_column_name="archived")
|
||||
land_asset_version = sa.sql.table(
|
||||
"land_asset_version",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("archived"),
|
||||
)
|
||||
cursor = op.get_bind().execute(land_asset_version.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
land_asset_version.update()
|
||||
.where(land_asset_version.c.uuid == row.uuid)
|
||||
.values({"archived": not row.archived})
|
||||
)
|
||||
|
||||
# structure
|
||||
op.alter_column("structure", "active", new_column_name="archived")
|
||||
structure = sa.sql.table(
|
||||
"structure",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("archived"),
|
||||
)
|
||||
cursor = op.get_bind().execute(structure.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
structure.update()
|
||||
.where(structure.c.uuid == row.uuid)
|
||||
.values({"archived": not row.archived})
|
||||
)
|
||||
op.alter_column("structure_version", "active", new_column_name="archived")
|
||||
structure_version = sa.sql.table(
|
||||
"structure_version",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("archived"),
|
||||
)
|
||||
cursor = op.get_bind().execute(structure_version.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
structure_version.update()
|
||||
.where(structure_version.c.uuid == row.uuid)
|
||||
.values({"archived": not row.archived})
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# structure
|
||||
op.alter_column("structure", "archived", new_column_name="active")
|
||||
structure = sa.sql.table(
|
||||
"structure",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("active"),
|
||||
)
|
||||
cursor = op.get_bind().execute(structure.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
structure.update()
|
||||
.where(structure.c.uuid == row.uuid)
|
||||
.values({"active": not row.active})
|
||||
)
|
||||
op.alter_column("structure_version", "archived", new_column_name="active")
|
||||
structure_version = sa.sql.table(
|
||||
"structure_version",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("active"),
|
||||
)
|
||||
cursor = op.get_bind().execute(structure_version.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
structure_version.update()
|
||||
.where(structure_version.c.uuid == row.uuid)
|
||||
.values({"active": not row.active})
|
||||
)
|
||||
|
||||
# land_asset
|
||||
op.alter_column("land_asset", "archived", new_column_name="active")
|
||||
land_asset = sa.sql.table(
|
||||
"land_asset",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("active"),
|
||||
)
|
||||
cursor = op.get_bind().execute(land_asset.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
land_asset.update()
|
||||
.where(land_asset.c.uuid == row.uuid)
|
||||
.values({"active": not row.active})
|
||||
)
|
||||
op.alter_column("land_asset_version", "archived", new_column_name="active")
|
||||
land_asset_version = sa.sql.table(
|
||||
"land_asset_version",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("active"),
|
||||
)
|
||||
cursor = op.get_bind().execute(land_asset_version.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
land_asset_version.update()
|
||||
.where(land_asset_version.c.uuid == row.uuid)
|
||||
.values({"active": not row.active})
|
||||
)
|
||||
|
||||
# group
|
||||
op.alter_column("group", "archived", new_column_name="active")
|
||||
group = sa.sql.table(
|
||||
"group",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("active"),
|
||||
)
|
||||
cursor = op.get_bind().execute(group.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
group.update()
|
||||
.where(group.c.uuid == row.uuid)
|
||||
.values({"active": not row.active})
|
||||
)
|
||||
op.alter_column("group_version", "archived", new_column_name="active")
|
||||
group_version = sa.sql.table(
|
||||
"group_version",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("active"),
|
||||
)
|
||||
cursor = op.get_bind().execute(group_version.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
group_version.update()
|
||||
.where(group_version.c.uuid == row.uuid)
|
||||
.values({"active": not row.active})
|
||||
)
|
||||
|
||||
# animal
|
||||
op.alter_column("animal", "archived", new_column_name="active")
|
||||
animal = sa.sql.table(
|
||||
"animal",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("active"),
|
||||
)
|
||||
cursor = op.get_bind().execute(animal.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
animal.update()
|
||||
.where(animal.c.uuid == row.uuid)
|
||||
.values({"active": not row.active})
|
||||
)
|
||||
op.alter_column("animal_version", "archived", new_column_name="active")
|
||||
animal_version = sa.sql.table(
|
||||
"animal_version",
|
||||
sa.sql.column("uuid"),
|
||||
sa.sql.column("active"),
|
||||
)
|
||||
cursor = op.get_bind().execute(animal_version.select())
|
||||
for row in cursor.fetchall():
|
||||
op.get_bind().execute(
|
||||
animal_version.update()
|
||||
.where(animal_version.c.uuid == row.uuid)
|
||||
.values({"active": not row.active})
|
||||
)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
"""add structure thumbnail url
|
||||
|
||||
Revision ID: 8cc1565d38e7
|
||||
Revises: 2a49127e974b
|
||||
Create Date: 2026-02-14 20:07:33.913573
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "8cc1565d38e7"
|
||||
down_revision: Union[str, None] = "2a49127e974b"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# structure
|
||||
op.add_column(
|
||||
"structure", sa.Column("thumbnail_url", sa.String(length=255), nullable=True)
|
||||
)
|
||||
op.add_column(
|
||||
"structure_version",
|
||||
sa.Column(
|
||||
"thumbnail_url", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# structure
|
||||
op.drop_column("structure_version", "thumbnail_url")
|
||||
op.drop_column("structure", "thumbnail_url")
|
||||
110
src/wuttafarm/db/alembic/versions/92b813360b99_add_groups.py
Normal file
110
src/wuttafarm/db/alembic/versions/92b813360b99_add_groups.py
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
"""add Groups
|
||||
|
||||
Revision ID: 92b813360b99
|
||||
Revises: 1b2d3224e5dc
|
||||
Create Date: 2026-02-13 13:09:48.718064
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "92b813360b99"
|
||||
down_revision: Union[str, None] = "1b2d3224e5dc"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# group
|
||||
op.create_table(
|
||||
"group",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("is_location", sa.Boolean(), nullable=False),
|
||||
sa.Column("is_fixed", sa.Boolean(), nullable=False),
|
||||
sa.Column("active", sa.Boolean(), nullable=False),
|
||||
sa.Column("notes", sa.Text(), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_group")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_group_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_group_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_group_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"group_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column("is_location", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("is_fixed", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("active", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.Text(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_group_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_group_version_end_transaction_id"),
|
||||
"group_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_group_version_operation_type"),
|
||||
"group_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_group_version_pk_transaction_id",
|
||||
"group_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_group_version_pk_validity",
|
||||
"group_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_group_version_transaction_id"),
|
||||
"group_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# group
|
||||
op.drop_index(op.f("ix_group_version_transaction_id"), table_name="group_version")
|
||||
op.drop_index("ix_group_version_pk_validity", table_name="group_version")
|
||||
op.drop_index("ix_group_version_pk_transaction_id", table_name="group_version")
|
||||
op.drop_index(op.f("ix_group_version_operation_type"), table_name="group_version")
|
||||
op.drop_index(
|
||||
op.f("ix_group_version_end_transaction_id"), table_name="group_version"
|
||||
)
|
||||
op.drop_table("group_version")
|
||||
op.drop_table("group")
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
"""add LogQuantity
|
||||
|
||||
Revision ID: 9e875e5cbdc1
|
||||
Revises: 74d32b4ec210
|
||||
Create Date: 2026-02-28 21:55:31.876087
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "9e875e5cbdc1"
|
||||
down_revision: Union[str, None] = "74d32b4ec210"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log_quantity
|
||||
op.create_table(
|
||||
"log_quantity",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("log_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("quantity_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["log_uuid"], ["log.uuid"], name=op.f("fk_log_quantity_log_uuid_log")
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["quantity_uuid"],
|
||||
["quantity.uuid"],
|
||||
name=op.f("fk_log_quantity_quantity_uuid_quantity"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_quantity")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_quantity_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"log_uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"quantity_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_quantity_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_quantity_version_end_transaction_id"),
|
||||
"log_quantity_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_quantity_version_operation_type"),
|
||||
"log_quantity_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_quantity_version_pk_transaction_id",
|
||||
"log_quantity_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_quantity_version_pk_validity",
|
||||
"log_quantity_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_quantity_version_transaction_id"),
|
||||
"log_quantity_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log_quantity
|
||||
op.drop_index(
|
||||
op.f("ix_log_quantity_version_transaction_id"),
|
||||
table_name="log_quantity_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_quantity_version_pk_validity", table_name="log_quantity_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_log_quantity_version_pk_transaction_id", table_name="log_quantity_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_quantity_version_operation_type"),
|
||||
table_name="log_quantity_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_quantity_version_end_transaction_id"),
|
||||
table_name="log_quantity_version",
|
||||
)
|
||||
op.drop_table("log_quantity_version")
|
||||
op.drop_table("log_quantity")
|
||||
110
src/wuttafarm/db/alembic/versions/9f2243df9566_add_land_types.py
Normal file
110
src/wuttafarm/db/alembic/versions/9f2243df9566_add_land_types.py
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
"""add Land Types
|
||||
|
||||
Revision ID: 9f2243df9566
|
||||
Revises: cf3f8f46d8bc
|
||||
Create Date: 2026-02-10 19:10:02.851756
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "9f2243df9566"
|
||||
down_revision: Union[str, None] = "cf3f8f46d8bc"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# land_type
|
||||
op.create_table(
|
||||
"land_type",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.String(length=50), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_land_type")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_land_type_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_land_type_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_land_type_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"land_type_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"drupal_id", sa.String(length=50), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_land_type_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_type_version_end_transaction_id"),
|
||||
"land_type_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_type_version_operation_type"),
|
||||
"land_type_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_land_type_version_pk_transaction_id",
|
||||
"land_type_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_land_type_version_pk_validity",
|
||||
"land_type_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_type_version_transaction_id"),
|
||||
"land_type_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# land_type
|
||||
op.drop_index(
|
||||
op.f("ix_land_type_version_transaction_id"), table_name="land_type_version"
|
||||
)
|
||||
op.drop_index("ix_land_type_version_pk_validity", table_name="land_type_version")
|
||||
op.drop_index(
|
||||
"ix_land_type_version_pk_transaction_id", table_name="land_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_type_version_operation_type"), table_name="land_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_type_version_end_transaction_id"), table_name="land_type_version"
|
||||
)
|
||||
op.drop_table("land_type_version")
|
||||
op.drop_table("land_type")
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
"""use shared base for Group Assets
|
||||
|
||||
Revision ID: aecfd9175624
|
||||
Revises: 34ec51d80f52
|
||||
Create Date: 2026-02-15 13:57:01.055304
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "aecfd9175624"
|
||||
down_revision: Union[str, None] = "34ec51d80f52"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# asset_group
|
||||
op.create_table(
|
||||
"asset_group",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["asset.uuid"], name=op.f("fk_asset_group_uuid_asset")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_group")),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_group_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_group_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_group_version_end_transaction_id"),
|
||||
"asset_group_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_group_version_operation_type"),
|
||||
"asset_group_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_group_version_pk_transaction_id",
|
||||
"asset_group_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_group_version_pk_validity",
|
||||
"asset_group_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_group_version_transaction_id"),
|
||||
"asset_group_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# group
|
||||
op.drop_index(
|
||||
op.f("ix_group_version_end_transaction_id"), table_name="group_version"
|
||||
)
|
||||
op.drop_index(op.f("ix_group_version_operation_type"), table_name="group_version")
|
||||
op.drop_index(
|
||||
op.f("ix_group_version_pk_transaction_id"), table_name="group_version"
|
||||
)
|
||||
op.drop_index(op.f("ix_group_version_pk_validity"), table_name="group_version")
|
||||
op.drop_index(op.f("ix_group_version_transaction_id"), table_name="group_version")
|
||||
op.drop_table("group_version")
|
||||
op.drop_table("group")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# group
|
||||
op.create_table(
|
||||
"group",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
||||
sa.Column("is_location", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("is_fixed", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_group")),
|
||||
sa.UniqueConstraint(
|
||||
"drupal_id",
|
||||
name=op.f("uq_group_drupal_id"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"farmos_uuid",
|
||||
name=op.f("uq_group_farmos_uuid"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"name",
|
||||
name=op.f("uq_group_name"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
)
|
||||
op.create_table(
|
||||
"group_version",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column("is_location", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("is_fixed", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column("transaction_id", sa.BIGINT(), autoincrement=False, nullable=False),
|
||||
sa.Column(
|
||||
"end_transaction_id", sa.BIGINT(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("operation_type", sa.SMALLINT(), autoincrement=False, nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_group_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_group_version_transaction_id"),
|
||||
"group_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_group_version_pk_validity"),
|
||||
"group_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_group_version_pk_transaction_id"),
|
||||
"group_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_group_version_operation_type"),
|
||||
"group_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_group_version_end_transaction_id"),
|
||||
"group_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# asset_group
|
||||
op.drop_index(
|
||||
op.f("ix_asset_group_version_transaction_id"), table_name="asset_group_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_group_version_pk_validity", table_name="asset_group_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_group_version_pk_transaction_id", table_name="asset_group_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_group_version_operation_type"), table_name="asset_group_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_group_version_end_transaction_id"),
|
||||
table_name="asset_group_version",
|
||||
)
|
||||
op.drop_table("asset_group_version")
|
||||
op.drop_table("asset_group")
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
"""remove AnimalType.changed
|
||||
|
||||
Revision ID: b8cd4a8f981f
|
||||
Revises: aecfd9175624
|
||||
Create Date: 2026-02-17 18:11:06.110003
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "b8cd4a8f981f"
|
||||
down_revision: Union[str, None] = "aecfd9175624"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# animal_type
|
||||
op.drop_column("animal_type", "changed")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# animal_type
|
||||
op.add_column(
|
||||
"animal_type",
|
||||
sa.Column(
|
||||
"changed", postgresql.TIMESTAMP(), autoincrement=False, nullable=True
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
"""add Asset Types
|
||||
|
||||
Revision ID: cf3f8f46d8bc
|
||||
Revises: 6c56bcd1c028
|
||||
Create Date: 2026-02-10 18:42:24.560312
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "cf3f8f46d8bc"
|
||||
down_revision: Union[str, None] = "6c56bcd1c028"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# asset_type
|
||||
op.create_table(
|
||||
"asset_type",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("description", sa.String(length=255), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.String(length=50), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_type")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_asset_type_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_asset_type_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_asset_type_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_type_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"description", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"drupal_id", sa.String(length=50), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_type_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_type_version_end_transaction_id"),
|
||||
"asset_type_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_type_version_operation_type"),
|
||||
"asset_type_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_type_version_pk_transaction_id",
|
||||
"asset_type_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_type_version_pk_validity",
|
||||
"asset_type_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_type_version_transaction_id"),
|
||||
"asset_type_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# asset_type
|
||||
op.drop_index(
|
||||
op.f("ix_asset_type_version_transaction_id"), table_name="asset_type_version"
|
||||
)
|
||||
op.drop_index("ix_asset_type_version_pk_validity", table_name="asset_type_version")
|
||||
op.drop_index(
|
||||
"ix_asset_type_version_pk_transaction_id", table_name="asset_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_type_version_operation_type"), table_name="asset_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_type_version_end_transaction_id"),
|
||||
table_name="asset_type_version",
|
||||
)
|
||||
op.drop_table("asset_type_version")
|
||||
op.drop_table("asset_type")
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
"""add MedicalLog.vet
|
||||
|
||||
Revision ID: d459db991404
|
||||
Revises: 9e875e5cbdc1
|
||||
Create Date: 2026-02-28 22:17:57.001134
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "d459db991404"
|
||||
down_revision: Union[str, None] = "9e875e5cbdc1"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log_medical
|
||||
op.add_column("log_medical", sa.Column("vet", sa.String(length=100), nullable=True))
|
||||
op.add_column(
|
||||
"log_medical_version",
|
||||
sa.Column("vet", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log_medical
|
||||
op.drop_column("log_medical_version", "vet")
|
||||
op.drop_column("log_medical", "vet")
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
"""add generic, animal assets
|
||||
|
||||
Revision ID: d6e8d16d6854
|
||||
Revises: 554e6168c339
|
||||
Create Date: 2026-02-15 09:11:04.886362
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "d6e8d16d6854"
|
||||
down_revision: Union[str, None] = "554e6168c339"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# animal
|
||||
op.drop_table("animal")
|
||||
op.drop_index(
|
||||
op.f("ix_animal_version_end_transaction_id"), table_name="animal_version"
|
||||
)
|
||||
op.drop_index(op.f("ix_animal_version_operation_type"), table_name="animal_version")
|
||||
op.drop_index(
|
||||
op.f("ix_animal_version_pk_transaction_id"), table_name="animal_version"
|
||||
)
|
||||
op.drop_index(op.f("ix_animal_version_pk_validity"), table_name="animal_version")
|
||||
op.drop_index(op.f("ix_animal_version_transaction_id"), table_name="animal_version")
|
||||
op.drop_table("animal_version")
|
||||
|
||||
# asset
|
||||
op.create_table(
|
||||
"asset",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.Column("asset_type", sa.String(length=100), nullable=False),
|
||||
sa.Column("asset_name", sa.String(length=100), nullable=False),
|
||||
sa.Column("is_location", sa.Boolean(), nullable=False),
|
||||
sa.Column("is_fixed", sa.Boolean(), nullable=False),
|
||||
sa.Column("notes", sa.Text(), nullable=True),
|
||||
sa.Column("thumbnail_url", sa.String(length=255), nullable=True),
|
||||
sa.Column("image_url", sa.String(length=255), nullable=True),
|
||||
sa.Column("archived", sa.Boolean(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["asset_type"],
|
||||
["asset_type.drupal_id"],
|
||||
name=op.f("fk_asset_asset_type_asset_type"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_asset_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_asset_farmos_uuid")),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"asset_type", sa.String(length=100), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"asset_name", sa.String(length=100), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("is_location", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("is_fixed", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.Text(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"thumbnail_url", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"image_url", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("archived", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_version_end_transaction_id"),
|
||||
"asset_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_version_operation_type"),
|
||||
"asset_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_version_pk_transaction_id",
|
||||
"asset_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_version_pk_validity",
|
||||
"asset_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_version_transaction_id"),
|
||||
"asset_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# asset_animal
|
||||
op.create_table(
|
||||
"asset_animal",
|
||||
sa.Column("animal_type_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("birthdate", sa.DateTime(), nullable=True),
|
||||
sa.Column("sex", sa.String(length=1), nullable=True),
|
||||
sa.Column("is_sterile", sa.Boolean(), nullable=True),
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["animal_type_uuid"],
|
||||
["animal_type.uuid"],
|
||||
name=op.f("fk_asset_animal_animal_type_uuid_animal_type"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["asset.uuid"], name=op.f("fk_asset_animal_uuid_asset")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_animal")),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_animal_version",
|
||||
sa.Column(
|
||||
"animal_type_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("birthdate", sa.DateTime(), autoincrement=False, nullable=True),
|
||||
sa.Column("sex", sa.String(length=1), autoincrement=False, nullable=True),
|
||||
sa.Column("is_sterile", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_animal_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_animal_version_end_transaction_id"),
|
||||
"asset_animal_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_animal_version_operation_type"),
|
||||
"asset_animal_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_animal_version_pk_transaction_id",
|
||||
"asset_animal_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_animal_version_pk_validity",
|
||||
"asset_animal_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_animal_version_transaction_id"),
|
||||
"asset_animal_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# asset_animal
|
||||
op.drop_index(
|
||||
op.f("ix_asset_animal_version_transaction_id"),
|
||||
table_name="asset_animal_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_animal_version_pk_validity", table_name="asset_animal_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_animal_version_pk_transaction_id", table_name="asset_animal_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_animal_version_operation_type"),
|
||||
table_name="asset_animal_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_animal_version_end_transaction_id"),
|
||||
table_name="asset_animal_version",
|
||||
)
|
||||
op.drop_table("asset_animal_version")
|
||||
op.drop_table("asset_animal")
|
||||
|
||||
# asset
|
||||
op.drop_index(op.f("ix_asset_version_transaction_id"), table_name="asset_version")
|
||||
op.drop_index("ix_asset_version_pk_validity", table_name="asset_version")
|
||||
op.drop_index("ix_asset_version_pk_transaction_id", table_name="asset_version")
|
||||
op.drop_index(op.f("ix_asset_version_operation_type"), table_name="asset_version")
|
||||
op.drop_index(
|
||||
op.f("ix_asset_version_end_transaction_id"), table_name="asset_version"
|
||||
)
|
||||
op.drop_table("asset_version")
|
||||
op.drop_table("asset")
|
||||
|
||||
# animal
|
||||
op.create_table(
|
||||
"animal",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
||||
sa.Column("animal_type_uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("birthdate", sa.DateTime(), autoincrement=False, nullable=True),
|
||||
sa.Column("sex", sa.VARCHAR(length=1), autoincrement=False, nullable=True),
|
||||
sa.Column("is_sterile", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"image_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"thumbnail_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["animal_type_uuid"],
|
||||
["animal_type.uuid"],
|
||||
name=op.f("fk_animal_animal_type_uuid_animal_type"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_animal")),
|
||||
sa.UniqueConstraint(
|
||||
"drupal_id",
|
||||
name=op.f("uq_animal_drupal_id"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"farmos_uuid",
|
||||
name=op.f("uq_animal_farmos_uuid"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
)
|
||||
op.create_table(
|
||||
"animal_version",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column("animal_type_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"birthdate", postgresql.TIMESTAMP(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("sex", sa.VARCHAR(length=1), autoincrement=False, nullable=True),
|
||||
sa.Column("is_sterile", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"image_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column("transaction_id", sa.BIGINT(), autoincrement=False, nullable=False),
|
||||
sa.Column(
|
||||
"end_transaction_id", sa.BIGINT(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("operation_type", sa.SMALLINT(), autoincrement=False, nullable=False),
|
||||
sa.Column(
|
||||
"thumbnail_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_animal_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_version_transaction_id"),
|
||||
"animal_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_version_pk_validity"),
|
||||
"animal_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_version_pk_transaction_id"),
|
||||
"animal_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_version_operation_type"),
|
||||
"animal_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_animal_version_end_transaction_id"),
|
||||
"animal_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
"""add Structure Types
|
||||
|
||||
Revision ID: d7479d7161a8
|
||||
Revises: 9f2243df9566
|
||||
Create Date: 2026-02-10 19:24:20.249826
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "d7479d7161a8"
|
||||
down_revision: Union[str, None] = "9f2243df9566"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# structure_type
|
||||
op.create_table(
|
||||
"structure_type",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.String(length=50), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_structure_type")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_structure_type_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_structure_type_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_structure_type_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"structure_type_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"drupal_id", sa.String(length=50), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_structure_type_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_type_version_end_transaction_id"),
|
||||
"structure_type_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_type_version_operation_type"),
|
||||
"structure_type_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_structure_type_version_pk_transaction_id",
|
||||
"structure_type_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_structure_type_version_pk_validity",
|
||||
"structure_type_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_structure_type_version_transaction_id"),
|
||||
"structure_type_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# structure_type
|
||||
op.drop_index(
|
||||
op.f("ix_structure_type_version_transaction_id"),
|
||||
table_name="structure_type_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_structure_type_version_pk_validity", table_name="structure_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_structure_type_version_pk_transaction_id",
|
||||
table_name="structure_type_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_structure_type_version_operation_type"),
|
||||
table_name="structure_type_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_structure_type_version_end_transaction_id"),
|
||||
table_name="structure_type_version",
|
||||
)
|
||||
op.drop_table("structure_type_version")
|
||||
op.drop_table("structure_type")
|
||||
|
|
@ -0,0 +1,411 @@
|
|||
"""use shared base for Land Assets
|
||||
|
||||
Revision ID: d882682c82f9
|
||||
Revises: d6e8d16d6854
|
||||
Create Date: 2026-02-15 12:00:27.036011
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "d882682c82f9"
|
||||
down_revision: Union[str, None] = "d6e8d16d6854"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# asset_parent
|
||||
op.create_table(
|
||||
"asset_parent",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("asset_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("parent_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["asset_uuid"],
|
||||
["asset.uuid"],
|
||||
name=op.f("fk_asset_parent_asset_uuid_asset"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["parent_uuid"],
|
||||
["asset.uuid"],
|
||||
name=op.f("fk_asset_parent_parent_uuid_asset"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_parent")),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_parent_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"asset_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"parent_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_parent_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_parent_version_end_transaction_id"),
|
||||
"asset_parent_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_parent_version_operation_type"),
|
||||
"asset_parent_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_parent_version_pk_transaction_id",
|
||||
"asset_parent_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_parent_version_pk_validity",
|
||||
"asset_parent_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_parent_version_transaction_id"),
|
||||
"asset_parent_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# asset_land
|
||||
op.create_table(
|
||||
"asset_land",
|
||||
sa.Column("land_type_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["land_type_uuid"],
|
||||
["land_type.uuid"],
|
||||
name=op.f("fk_asset_land_land_type_uuid_land_type"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["uuid"], ["asset.uuid"], name=op.f("fk_asset_land_uuid_asset")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_land")),
|
||||
sa.UniqueConstraint(
|
||||
"land_type_uuid", name=op.f("uq_asset_land_land_type_uuid")
|
||||
),
|
||||
)
|
||||
op.create_table(
|
||||
"asset_land_version",
|
||||
sa.Column(
|
||||
"land_type_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_asset_land_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_land_version_end_transaction_id"),
|
||||
"asset_land_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_land_version_operation_type"),
|
||||
"asset_land_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_land_version_pk_transaction_id",
|
||||
"asset_land_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_asset_land_version_pk_validity",
|
||||
"asset_land_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_asset_land_version_transaction_id"),
|
||||
"asset_land_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# land_asset_parent
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_parent_version_end_transaction_id"),
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_parent_version_operation_type"),
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_parent_version_pk_transaction_id"),
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_parent_version_pk_validity"),
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_parent_version_transaction_id"),
|
||||
table_name="land_asset_parent_version",
|
||||
)
|
||||
op.drop_table("land_asset_parent_version")
|
||||
op.drop_table("land_asset_parent")
|
||||
|
||||
# land_asset
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_version_end_transaction_id"),
|
||||
table_name="land_asset_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_version_operation_type"), table_name="land_asset_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_version_pk_transaction_id"), table_name="land_asset_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_version_pk_validity"), table_name="land_asset_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_version_transaction_id"), table_name="land_asset_version"
|
||||
)
|
||||
op.drop_table("land_asset_version")
|
||||
op.drop_table("land_asset")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# land_asset
|
||||
op.create_table(
|
||||
"land_asset",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
||||
sa.Column("land_type_uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("is_location", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("is_fixed", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["land_type_uuid"],
|
||||
["land_type.uuid"],
|
||||
name=op.f("fk_land_asset_land_type_uuid_land_type"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_land_asset")),
|
||||
sa.UniqueConstraint(
|
||||
"drupal_id",
|
||||
name=op.f("uq_land_asset_drupal_id"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"farmos_uuid",
|
||||
name=op.f("uq_land_asset_farmos_uuid"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"land_type_uuid",
|
||||
name=op.f("uq_land_asset_land_type_uuid"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"name",
|
||||
name=op.f("uq_land_asset_name"),
|
||||
postgresql_include=[],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
),
|
||||
)
|
||||
op.create_table(
|
||||
"land_asset_version",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column("land_type_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("is_location", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("is_fixed", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column("transaction_id", sa.BIGINT(), autoincrement=False, nullable=False),
|
||||
sa.Column(
|
||||
"end_transaction_id", sa.BIGINT(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("operation_type", sa.SMALLINT(), autoincrement=False, nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_land_asset_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_version_transaction_id"),
|
||||
"land_asset_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_version_pk_validity"),
|
||||
"land_asset_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_version_pk_transaction_id"),
|
||||
"land_asset_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_version_operation_type"),
|
||||
"land_asset_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_version_end_transaction_id"),
|
||||
"land_asset_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# land_asset_parent
|
||||
op.create_table(
|
||||
"land_asset_parent",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("land_asset_uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("parent_asset_uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["land_asset_uuid"],
|
||||
["land_asset.uuid"],
|
||||
name=op.f("fk_land_asset_parent_land_asset_uuid_land_asset"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["parent_asset_uuid"],
|
||||
["land_asset.uuid"],
|
||||
name=op.f("fk_land_asset_parent_parent_asset_uuid_land_asset"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_land_asset_parent")),
|
||||
)
|
||||
op.create_table(
|
||||
"land_asset_parent_version",
|
||||
sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False),
|
||||
sa.Column("land_asset_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("parent_asset_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
sa.Column("transaction_id", sa.BIGINT(), autoincrement=False, nullable=False),
|
||||
sa.Column(
|
||||
"end_transaction_id", sa.BIGINT(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("operation_type", sa.SMALLINT(), autoincrement=False, nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_land_asset_parent_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_parent_version_transaction_id"),
|
||||
"land_asset_parent_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_parent_version_pk_validity"),
|
||||
"land_asset_parent_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_parent_version_pk_transaction_id"),
|
||||
"land_asset_parent_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_parent_version_operation_type"),
|
||||
"land_asset_parent_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_parent_version_end_transaction_id"),
|
||||
"land_asset_parent_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# asset_land
|
||||
op.drop_table("asset_land")
|
||||
op.drop_index(
|
||||
op.f("ix_asset_land_version_transaction_id"), table_name="asset_land_version"
|
||||
)
|
||||
op.drop_index("ix_asset_land_version_pk_validity", table_name="asset_land_version")
|
||||
op.drop_index(
|
||||
"ix_asset_land_version_pk_transaction_id", table_name="asset_land_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_land_version_operation_type"), table_name="asset_land_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_land_version_end_transaction_id"),
|
||||
table_name="asset_land_version",
|
||||
)
|
||||
op.drop_table("asset_land_version")
|
||||
|
||||
# asset_parent
|
||||
op.drop_index(
|
||||
op.f("ix_asset_parent_version_transaction_id"),
|
||||
table_name="asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_parent_version_pk_validity", table_name="asset_parent_version"
|
||||
)
|
||||
op.drop_index(
|
||||
"ix_asset_parent_version_pk_transaction_id", table_name="asset_parent_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_parent_version_operation_type"),
|
||||
table_name="asset_parent_version",
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_asset_parent_version_end_transaction_id"),
|
||||
table_name="asset_parent_version",
|
||||
)
|
||||
op.drop_table("asset_parent_version")
|
||||
op.drop_table("asset_parent")
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
"""add generic log base
|
||||
|
||||
Revision ID: dd6351e69233
|
||||
Revises: b8cd4a8f981f
|
||||
Create Date: 2026-02-18 12:09:05.200134
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "dd6351e69233"
|
||||
down_revision: Union[str, None] = "b8cd4a8f981f"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log
|
||||
op.create_table(
|
||||
"log",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("log_type", sa.String(length=100), nullable=False),
|
||||
sa.Column("message", sa.String(length=255), nullable=False),
|
||||
sa.Column("timestamp", sa.DateTime(), nullable=False),
|
||||
sa.Column("status", sa.String(length=20), nullable=False),
|
||||
sa.Column("notes", sa.Text(), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["log_type"], ["log_type.drupal_id"], name=op.f("fk_log_log_type_log_type")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_log_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_log_farmos_uuid")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column(
|
||||
"log_type", sa.String(length=100), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("message", sa.String(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column("timestamp", sa.DateTime(), autoincrement=False, nullable=True),
|
||||
sa.Column("status", sa.String(length=20), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.Text(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint("uuid", "transaction_id", name=op.f("pk_log_version")),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_version_end_transaction_id"),
|
||||
"log_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_version_operation_type"),
|
||||
"log_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_version_pk_transaction_id",
|
||||
"log_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_version_pk_validity",
|
||||
"log_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_version_transaction_id"),
|
||||
"log_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# log_activity
|
||||
op.drop_column("log_activity_version", "status")
|
||||
op.drop_column("log_activity_version", "farmos_uuid")
|
||||
op.drop_column("log_activity_version", "timestamp")
|
||||
op.drop_column("log_activity_version", "message")
|
||||
op.drop_column("log_activity_version", "drupal_id")
|
||||
op.drop_column("log_activity_version", "notes")
|
||||
op.drop_constraint(
|
||||
op.f("uq_log_activity_drupal_id"), "log_activity", type_="unique"
|
||||
)
|
||||
op.drop_constraint(
|
||||
op.f("uq_log_activity_farmos_uuid"), "log_activity", type_="unique"
|
||||
)
|
||||
op.create_foreign_key(
|
||||
op.f("fk_log_activity_uuid_log"), "log_activity", "log", ["uuid"], ["uuid"]
|
||||
)
|
||||
op.drop_column("log_activity", "status")
|
||||
op.drop_column("log_activity", "farmos_uuid")
|
||||
op.drop_column("log_activity", "timestamp")
|
||||
op.drop_column("log_activity", "message")
|
||||
op.drop_column("log_activity", "drupal_id")
|
||||
op.drop_column("log_activity", "notes")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log_activity
|
||||
op.add_column(
|
||||
"log_activity",
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity",
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity",
|
||||
sa.Column(
|
||||
"message", sa.VARCHAR(length=255), autoincrement=False, nullable=False
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity",
|
||||
sa.Column(
|
||||
"timestamp", postgresql.TIMESTAMP(), autoincrement=False, nullable=False
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity",
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity",
|
||||
sa.Column("status", sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.drop_constraint(
|
||||
op.f("fk_log_activity_uuid_log"), "log_activity", type_="foreignkey"
|
||||
)
|
||||
op.create_unique_constraint(
|
||||
op.f("uq_log_activity_farmos_uuid"),
|
||||
"log_activity",
|
||||
["farmos_uuid"],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
)
|
||||
op.create_unique_constraint(
|
||||
op.f("uq_log_activity_drupal_id"),
|
||||
"log_activity",
|
||||
["drupal_id"],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity_version",
|
||||
sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity_version",
|
||||
sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity_version",
|
||||
sa.Column(
|
||||
"message", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity_version",
|
||||
sa.Column(
|
||||
"timestamp", postgresql.TIMESTAMP(), autoincrement=False, nullable=True
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity_version",
|
||||
sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"log_activity_version",
|
||||
sa.Column("status", sa.VARCHAR(length=20), autoincrement=False, nullable=True),
|
||||
)
|
||||
|
||||
# log
|
||||
op.drop_index(op.f("ix_log_version_transaction_id"), table_name="log_version")
|
||||
op.drop_index("ix_log_version_pk_validity", table_name="log_version")
|
||||
op.drop_index("ix_log_version_pk_transaction_id", table_name="log_version")
|
||||
op.drop_index(op.f("ix_log_version_operation_type"), table_name="log_version")
|
||||
op.drop_index(op.f("ix_log_version_end_transaction_id"), table_name="log_version")
|
||||
op.drop_table("log_version")
|
||||
op.drop_table("log")
|
||||
114
src/wuttafarm/db/alembic/versions/e0d9f72575d6_add_log_types.py
Normal file
114
src/wuttafarm/db/alembic/versions/e0d9f72575d6_add_log_types.py
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
"""add Log Types
|
||||
|
||||
Revision ID: e0d9f72575d6
|
||||
Revises: d7479d7161a8
|
||||
Create Date: 2026-02-10 19:35:06.631814
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "e0d9f72575d6"
|
||||
down_revision: Union[str, None] = "d7479d7161a8"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log_type
|
||||
op.create_table(
|
||||
"log_type",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("description", sa.String(length=255), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.String(length=50), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_log_type")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_log_type_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_log_type_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_log_type_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"log_type_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"description", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"drupal_id", sa.String(length=50), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_log_type_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_type_version_end_transaction_id"),
|
||||
"log_type_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_type_version_operation_type"),
|
||||
"log_type_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_type_version_pk_transaction_id",
|
||||
"log_type_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_log_type_version_pk_validity",
|
||||
"log_type_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_log_type_version_transaction_id"),
|
||||
"log_type_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log_type
|
||||
op.drop_index(
|
||||
op.f("ix_log_type_version_transaction_id"), table_name="log_type_version"
|
||||
)
|
||||
op.drop_index("ix_log_type_version_pk_validity", table_name="log_type_version")
|
||||
op.drop_index(
|
||||
"ix_log_type_version_pk_transaction_id", table_name="log_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_type_version_operation_type"), table_name="log_type_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_log_type_version_end_transaction_id"), table_name="log_type_version"
|
||||
)
|
||||
op.drop_table("log_type_version")
|
||||
op.drop_table("log_type")
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
"""add Land Assets
|
||||
|
||||
Revision ID: e416b96467fc
|
||||
Revises: e0d9f72575d6
|
||||
Create Date: 2026-02-13 09:39:31.327442
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "e416b96467fc"
|
||||
down_revision: Union[str, None] = "e0d9f72575d6"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# land_asset
|
||||
op.create_table(
|
||||
"land_asset",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("land_type_uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("is_location", sa.Boolean(), nullable=False),
|
||||
sa.Column("is_fixed", sa.Boolean(), nullable=False),
|
||||
sa.Column("notes", sa.Text(), nullable=True),
|
||||
sa.Column("active", sa.Boolean(), nullable=False),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["land_type_uuid"],
|
||||
["land_type.uuid"],
|
||||
name=op.f("fk_land_asset_land_type_uuid_land_type"),
|
||||
),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_land_asset")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_land_asset_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_land_asset_farmos_uuid")),
|
||||
sa.UniqueConstraint(
|
||||
"land_type_uuid", name=op.f("uq_land_asset_land_type_uuid")
|
||||
),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_land_asset_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"land_asset_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"land_type_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("is_location", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("is_fixed", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column("notes", sa.Text(), autoincrement=False, nullable=True),
|
||||
sa.Column("active", sa.Boolean(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"uuid", "transaction_id", name=op.f("pk_land_asset_version")
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_version_end_transaction_id"),
|
||||
"land_asset_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_version_operation_type"),
|
||||
"land_asset_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_land_asset_version_pk_transaction_id",
|
||||
"land_asset_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_land_asset_version_pk_validity",
|
||||
"land_asset_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_land_asset_version_transaction_id"),
|
||||
"land_asset_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# land_asset
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_version_transaction_id"), table_name="land_asset_version"
|
||||
)
|
||||
op.drop_index("ix_land_asset_version_pk_validity", table_name="land_asset_version")
|
||||
op.drop_index(
|
||||
"ix_land_asset_version_pk_transaction_id", table_name="land_asset_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_version_operation_type"), table_name="land_asset_version"
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_land_asset_version_end_transaction_id"),
|
||||
table_name="land_asset_version",
|
||||
)
|
||||
op.drop_table("land_asset_version")
|
||||
op.drop_table("land_asset")
|
||||
102
src/wuttafarm/db/alembic/versions/ea88e72a5fa5_add_units.py
Normal file
102
src/wuttafarm/db/alembic/versions/ea88e72a5fa5_add_units.py
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
"""add Units
|
||||
|
||||
Revision ID: ea88e72a5fa5
|
||||
Revises: 82a03f4ef1a4
|
||||
Create Date: 2026-02-18 20:01:40.720138
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "ea88e72a5fa5"
|
||||
down_revision: Union[str, None] = "82a03f4ef1a4"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# unit
|
||||
op.create_table(
|
||||
"unit",
|
||||
sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column("description", sa.String(length=255), nullable=True),
|
||||
sa.Column("farmos_uuid", wuttjamaican.db.util.UUID(), nullable=True),
|
||||
sa.Column("drupal_id", sa.Integer(), nullable=True),
|
||||
sa.PrimaryKeyConstraint("uuid", name=op.f("pk_unit")),
|
||||
sa.UniqueConstraint("drupal_id", name=op.f("uq_unit_drupal_id")),
|
||||
sa.UniqueConstraint("farmos_uuid", name=op.f("uq_unit_farmos_uuid")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_unit_name")),
|
||||
)
|
||||
op.create_table(
|
||||
"unit_version",
|
||||
sa.Column(
|
||||
"uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("name", sa.String(length=100), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"description", sa.String(length=255), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column(
|
||||
"farmos_uuid",
|
||||
wuttjamaican.db.util.UUID(),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("drupal_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||
),
|
||||
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint("uuid", "transaction_id", name=op.f("pk_unit_version")),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_unit_version_end_transaction_id"),
|
||||
"unit_version",
|
||||
["end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_unit_version_operation_type"),
|
||||
"unit_version",
|
||||
["operation_type"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_unit_version_pk_transaction_id",
|
||||
"unit_version",
|
||||
["uuid", sa.literal_column("transaction_id DESC")],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_unit_version_pk_validity",
|
||||
"unit_version",
|
||||
["uuid", "transaction_id", "end_transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_unit_version_transaction_id"),
|
||||
"unit_version",
|
||||
["transaction_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# unit
|
||||
op.drop_index(op.f("ix_unit_version_transaction_id"), table_name="unit_version")
|
||||
op.drop_index("ix_unit_version_pk_validity", table_name="unit_version")
|
||||
op.drop_index("ix_unit_version_pk_transaction_id", table_name="unit_version")
|
||||
op.drop_index(op.f("ix_unit_version_operation_type"), table_name="unit_version")
|
||||
op.drop_index(op.f("ix_unit_version_end_transaction_id"), table_name="unit_version")
|
||||
op.drop_table("unit_version")
|
||||
op.drop_table("unit")
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
"""add Log.is_group_assignment
|
||||
|
||||
Revision ID: f3c7e273bfa3
|
||||
Revises: 47d0ebd84554
|
||||
Create Date: 2026-02-28 20:04:40.700474
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import wuttjamaican.db.util
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "f3c7e273bfa3"
|
||||
down_revision: Union[str, None] = "47d0ebd84554"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
# log
|
||||
op.add_column("log", sa.Column("is_group_assignment", sa.Boolean(), nullable=True))
|
||||
op.add_column(
|
||||
"log_version",
|
||||
sa.Column(
|
||||
"is_group_assignment", sa.Boolean(), autoincrement=False, nullable=True
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
# log
|
||||
op.drop_column("log_version", "is_group_assignment")
|
||||
op.drop_column("log", "is_group_assignment")
|
||||
|
|
@ -26,4 +26,20 @@ WuttaFarm data models
|
|||
# bring in all of wutta
|
||||
from wuttjamaican.db.model import *
|
||||
|
||||
# TODO: import other/custom models here...
|
||||
# wutta model extensions
|
||||
from .users import WuttaFarmUser
|
||||
|
||||
# wuttafarm proper models
|
||||
from .unit import Unit, Measure
|
||||
from .quantities import QuantityType, Quantity, StandardQuantity
|
||||
from .asset import AssetType, Asset, AssetParent
|
||||
from .asset_land import LandType, LandAsset
|
||||
from .asset_structure import StructureType, StructureAsset
|
||||
from .asset_animal import AnimalType, AnimalAsset
|
||||
from .asset_group import GroupAsset
|
||||
from .asset_plant import PlantType, PlantAsset, PlantAssetPlantType
|
||||
from .log import LogType, Log, LogAsset, LogGroup, LogLocation, LogQuantity, LogOwner
|
||||
from .log_activity import ActivityLog
|
||||
from .log_harvest import HarvestLog
|
||||
from .log_medical import MedicalLog
|
||||
from .log_observation import ObservationLog
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue