Set up alembic, and more
- Setup alembic and generate the initial migration - Add poethepoet to dev dependencies in order to put hard-to-remember commands beneath the poetry namespace - Add psycopg2-binary dependency, for use with postgresql - Remove dotenv dependency, as it is no longer required - Add `config.toml` to gitignore. This is because alembic has no argument parser that will let you specify the config file to use. Developers are encouraged to use `config.toml`, which will be automatically recognized, unless they want to implement the argument parser functionality for alembic.
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -20,4 +20,6 @@ venv.bak/ | ||||
|  | ||||
| dist/ | ||||
|  | ||||
| result | ||||
| result | ||||
|  | ||||
| config.toml | ||||
							
								
								
									
										110
									
								
								alembic.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								alembic.ini
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| # A generic, single database configuration. | ||||
|  | ||||
| [alembic] | ||||
| # path to migration scripts | ||||
| script_location = worblehat/models/migrations | ||||
|  | ||||
| # template used to generate migration file names; The default value is %%(rev)s_%%(slug)s | ||||
| # Uncomment the line below if you want the files to be prepended with date and time | ||||
| # see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file | ||||
| # for all available tokens | ||||
| file_template = %%(year)d-%%(month).2d-%%(day).2dT%%(hour).2d%%(minute).2d_%%(rev)s_%%(slug)s | ||||
|  | ||||
| # sys.path path, will be prepended to sys.path if present. | ||||
| # defaults to the current working directory. | ||||
| prepend_sys_path = . | ||||
|  | ||||
| # timezone to use when rendering the date within the migration file | ||||
| # as well as the filename. | ||||
| # If specified, requires the python-dateutil library that can be | ||||
| # installed by adding `alembic[tz]` to the pip requirements | ||||
| # string value is passed to dateutil.tz.gettz() | ||||
| # leave blank for localtime | ||||
| # timezone = | ||||
|  | ||||
| # max length of characters to apply to the | ||||
| # "slug" field | ||||
| # truncate_slug_length = 40 | ||||
|  | ||||
| # set to 'true' to run the environment during | ||||
| # the 'revision' command, regardless of autogenerate | ||||
| revision_environment = true | ||||
|  | ||||
| # set to 'true' to allow .pyc and .pyo files without | ||||
| # a source .py file to be detected as revisions in the | ||||
| # versions/ directory | ||||
| # sourceless = false | ||||
|  | ||||
| # version location specification; This defaults | ||||
| # to worblehat/models/migrations/versions.  When using multiple version | ||||
| # directories, initial revisions must be specified with --version-path. | ||||
| # The path separator used here should be the separator specified by "version_path_separator" below. | ||||
| # version_locations = %(here)s/bar:%(here)s/bat:worblehat/models/migrations/versions | ||||
|  | ||||
| # version path separator; As mentioned above, this is the character used to split | ||||
| # version_locations. The default within new alembic.ini files is "os", which uses os.pathsep. | ||||
| # If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas. | ||||
| # Valid values for version_path_separator are: | ||||
| # | ||||
| # version_path_separator = : | ||||
| # version_path_separator = ; | ||||
| # version_path_separator = space | ||||
| version_path_separator = os  # Use os.pathsep. Default configuration used for new projects. | ||||
|  | ||||
| # set to 'true' to search source files recursively | ||||
| # in each "version_locations" directory | ||||
| # new in Alembic version 1.10 | ||||
| # recursive_version_locations = false | ||||
|  | ||||
| # the output encoding used when revision files | ||||
| # are written from script.py.mako | ||||
| # output_encoding = utf-8 | ||||
|  | ||||
| # sqlalchemy.url = driver://user:pass@localhost/dbname | ||||
|  | ||||
|  | ||||
| [post_write_hooks] | ||||
| # post_write_hooks defines scripts or Python functions that are run | ||||
| # on newly generated revision scripts.  See the documentation for further | ||||
| # detail and examples | ||||
|  | ||||
| # format using "black" - use the console_scripts runner, against the "black" entrypoint | ||||
| # hooks = black | ||||
| # black.type = console_scripts | ||||
| # black.entrypoint = black | ||||
| # black.options = -l 79 REVISION_SCRIPT_FILENAME | ||||
|  | ||||
| # Logging configuration | ||||
| [loggers] | ||||
| keys = root,sqlalchemy,alembic | ||||
|  | ||||
| [handlers] | ||||
| keys = console | ||||
|  | ||||
| [formatters] | ||||
| keys = generic | ||||
|  | ||||
| [logger_root] | ||||
| level = WARN | ||||
| handlers = console | ||||
| qualname = | ||||
|  | ||||
| [logger_sqlalchemy] | ||||
| level = WARN | ||||
| handlers = | ||||
| qualname = sqlalchemy.engine | ||||
|  | ||||
| [logger_alembic] | ||||
| level = INFO | ||||
| handlers = | ||||
| qualname = alembic | ||||
|  | ||||
| [handler_console] | ||||
| class = StreamHandler | ||||
| args = (sys.stderr,) | ||||
| level = NOTSET | ||||
| formatter = generic | ||||
|  | ||||
| [formatter_generic] | ||||
| format = %(levelname)-5.5s [%(name)s] %(message)s | ||||
| datefmt = %H:%M:%S | ||||
							
								
								
									
										118
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										118
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							| @@ -315,19 +315,107 @@ files = [ | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "python-dotenv" | ||||
| version = "1.0.0" | ||||
| description = "Read key-value pairs from a .env file and set them as environment variables" | ||||
| category = "main" | ||||
| name = "pastel" | ||||
| version = "0.2.1" | ||||
| description = "Bring colors to your terminal." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" | ||||
| files = [ | ||||
|     {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, | ||||
|     {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "poethepoet" | ||||
| version = "0.20.0" | ||||
| description = "A task runner that works well with poetry." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.8" | ||||
| files = [ | ||||
|     {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, | ||||
|     {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, | ||||
|     {file = "poethepoet-0.20.0-py3-none-any.whl", hash = "sha256:cb37be15f3895ccc65ddf188c2e3d8fb79e26cc9d469a6098cb1c6f994659f6f"}, | ||||
|     {file = "poethepoet-0.20.0.tar.gz", hash = "sha256:ca5a2a955f52dfb0a53fad3c989ef0b69ce3d5ec0f6bfa9b1da1f9e32d262e20"}, | ||||
| ] | ||||
|  | ||||
| [package.dependencies] | ||||
| pastel = ">=0.2.1,<0.3.0" | ||||
| tomli = ">=1.2.2" | ||||
|  | ||||
| [package.extras] | ||||
| cli = ["click (>=5.0)"] | ||||
| poetry-plugin = ["poetry (>=1.0,<2.0)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "psycopg2-binary" | ||||
| version = "2.9.6" | ||||
| description = "psycopg2 - Python-PostgreSQL Database Adapter" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
| files = [ | ||||
|     {file = "psycopg2-binary-2.9.6.tar.gz", hash = "sha256:1f64dcfb8f6e0c014c7f55e51c9759f024f70ea572fbdef123f85318c297947c"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d26e0342183c762de3276cca7a530d574d4e25121ca7d6e4a98e4f05cb8e4df7"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c48d8f2db17f27d41fb0e2ecd703ea41984ee19362cbce52c097963b3a1b4365"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffe9dc0a884a8848075e576c1de0290d85a533a9f6e9c4e564f19adf8f6e54a7"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a76e027f87753f9bd1ab5f7c9cb8c7628d1077ef927f5e2446477153a602f2c"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6460c7a99fc939b849431f1e73e013d54aa54293f30f1109019c56a0b2b2ec2f"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae102a98c547ee2288637af07393dd33f440c25e5cd79556b04e3fca13325e5f"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9972aad21f965599ed0106f65334230ce826e5ae69fda7cbd688d24fa922415e"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a40c00dbe17c0af5bdd55aafd6ff6679f94a9be9513a4c7e071baf3d7d22a70"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:cacbdc5839bdff804dfebc058fe25684cae322987f7a38b0168bc1b2df703fb1"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f0438fa20fb6c7e202863e0d5ab02c246d35efb1d164e052f2f3bfe2b152bd0"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-win32.whl", hash = "sha256:b6c8288bb8a84b47e07013bb4850f50538aa913d487579e1921724631d02ea1b"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:61b047a0537bbc3afae10f134dc6393823882eb263088c271331602b672e52e9"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:964b4dfb7c1c1965ac4c1978b0f755cc4bd698e8aa2b7667c575fb5f04ebe06b"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afe64e9b8ea66866a771996f6ff14447e8082ea26e675a295ad3bdbffdd72afb"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15e2ee79e7cf29582ef770de7dab3d286431b01c3bb598f8e05e09601b890081"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa74c903a3c1f0d9b1c7e7b53ed2d929a4910e272add6700c38f365a6002820"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b83456c2d4979e08ff56180a76429263ea254c3f6552cd14ada95cff1dec9bb8"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0645376d399bfd64da57148694d78e1f431b1e1ee1054872a5713125681cf1be"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e99e34c82309dd78959ba3c1590975b5d3c862d6f279f843d47d26ff89d7d7e1"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4ea29fc3ad9d91162c52b578f211ff1c931d8a38e1f58e684c45aa470adf19e2"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4ac30da8b4f57187dbf449294d23b808f8f53cad6b1fc3623fa8a6c11d176dd0"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e78e6e2a00c223e164c417628572a90093c031ed724492c763721c2e0bc2a8df"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-win32.whl", hash = "sha256:1876843d8e31c89c399e31b97d4b9725a3575bb9c2af92038464231ec40f9edb"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:b4b24f75d16a89cc6b4cdff0eb6a910a966ecd476d1e73f7ce5985ff1328e9a6"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp36-cp36m-win32.whl", hash = "sha256:498807b927ca2510baea1b05cc91d7da4718a0f53cb766c154c417a39f1820a0"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0d236c2825fa656a2d98bbb0e52370a2e852e5a0ec45fc4f402977313329174d"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:34b9ccdf210cbbb1303c7c4db2905fa0319391bd5904d32689e6dd5c963d2ea8"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d2222e61f313c4848ff05353653bf5f5cf6ce34df540e4274516880d9c3763"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30637a20623e2a2eacc420059be11527f4458ef54352d870b8181a4c3020ae6b"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8122cfc7cae0da9a3077216528b8bb3629c43b25053284cc868744bfe71eb141"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38601cbbfe600362c43714482f43b7c110b20cb0f8172422c616b09b85a750c5"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c7e62ab8b332147a7593a385d4f368874d5fe4ad4e341770d4983442d89603e3"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2ab652e729ff4ad76d400df2624d223d6e265ef81bb8aa17fbd63607878ecbee"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c83a74b68270028dc8ee74d38ecfaf9c90eed23c8959fca95bd703d25b82c88e"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d4e6036decf4b72d6425d5b29bbd3e8f0ff1059cda7ac7b96d6ac5ed34ffbacd"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-win32.whl", hash = "sha256:a8c28fd40a4226b4a84bdf2d2b5b37d2c7bd49486b5adcc200e8c7ec991dfa7e"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:51537e3d299be0db9137b321dfb6a5022caaab275775680e0c3d281feefaca6b"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4499e0a83b7b7edcb8dabecbd8501d0d3a5ef66457200f77bde3d210d5debb"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7e13a5a2c01151f1208d5207e42f33ba86d561b7a89fca67c700b9486a06d0e2"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e0f754d27fddcfd74006455b6e04e6705d6c31a612ec69ddc040a5468e44b4e"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d57c3fd55d9058645d26ae37d76e61156a27722097229d32a9e73ed54819982a"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71f14375d6f73b62800530b581aed3ada394039877818b2d5f7fc77e3bb6894d"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:441cc2f8869a4f0f4bb408475e5ae0ee1f3b55b33f350406150277f7f35384fc"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:65bee1e49fa6f9cf327ce0e01c4c10f39165ee76d35c846ade7cb0ec6683e303"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:af335bac6b666cc6aea16f11d486c3b794029d9df029967f9938a4bed59b6a19"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cfec476887aa231b8548ece2e06d28edc87c1397ebd83922299af2e051cf2827"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65c07febd1936d63bfde78948b76cd4c2a411572a44ac50719ead41947d0f26b"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-win32.whl", hash = "sha256:4dfb4be774c4436a4526d0c554af0cc2e02082c38303852a36f6456ece7b3503"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:02c6e3cf3439e213e4ee930308dc122d6fb4d4bea9aef4a12535fbd605d1a2fe"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9182eb20f41417ea1dd8e8f7888c4d7c6e805f8a7c98c1081778a3da2bee3e4"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8a6979cf527e2603d349a91060f428bcb135aea2be3201dff794813256c274f1"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8338a271cb71d8da40b023a35d9c1e919eba6cbd8fa20a54b748a332c355d896"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ed340d2b858d6e6fb5083f87c09996506af483227735de6964a6100b4e6a54"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f81e65376e52f03422e1fb475c9514185669943798ed019ac50410fb4c4df232"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfb13af3c5dd3a9588000910178de17010ebcccd37b4f9794b00595e3a8ddad3"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4c727b597c6444a16e9119386b59388f8a424223302d0c06c676ec8b4bc1f963"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d67fbdaf177da06374473ef6f7ed8cc0a9dc640b01abfe9e8a2ccb1b1402c1f"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0892ef645c2fabb0c75ec32d79f4252542d0caec1d5d949630e7d242ca4681a3"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:02c0f3757a4300cf379eb49f543fb7ac527fb00144d39246ee40e1df684ab514"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-win32.whl", hash = "sha256:c3dba7dab16709a33a847e5cd756767271697041fbe3fe97c215b1fc1f5c9848"}, | ||||
|     {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"}, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "sqlalchemy" | ||||
| @@ -407,6 +495,18 @@ postgresql-psycopg2cffi = ["psycopg2cffi"] | ||||
| pymysql = ["pymysql"] | ||||
| sqlcipher = ["sqlcipher3-binary"] | ||||
|  | ||||
| [[package]] | ||||
| name = "tomli" | ||||
| version = "2.0.1" | ||||
| description = "A lil' TOML parser" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
| files = [ | ||||
|     {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, | ||||
|     {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "typing-extensions" | ||||
| version = "4.5.0" | ||||
| @@ -457,5 +557,5 @@ email = ["email-validator"] | ||||
|  | ||||
| [metadata] | ||||
| lock-version = "2.0" | ||||
| python-versions = "^3.10" | ||||
| content-hash = "5d3f98b7404ad05269ae8b89d054613fcde49608e826d90f38b93f8d76a763d5" | ||||
| python-versions = "^3.11" | ||||
| content-hash = "123df985006374b7c4ede4587a2facef89306039e35af84ddc9c516eecd46c89" | ||||
|   | ||||
| @@ -14,16 +14,33 @@ flask-admin = "^1.6.1" | ||||
| flask-sqlalchemy = "^3.0.3" | ||||
| isbnlib = "^3.10.14" | ||||
| python = "^3.11" | ||||
| python-dotenv = "^1.0.0" | ||||
| sqlalchemy = "^2.0.8" | ||||
| psycopg2-binary = "^2.9.6" | ||||
|  | ||||
| [tool.poetry.group.dev.dependencies] | ||||
| werkzeug = "^2.3.3" | ||||
| poethepoet = "^0.20.0" | ||||
|  | ||||
| [tool.poetry.scripts] | ||||
| cli = "worblehat.cli.main:main" | ||||
| dev = "worblehat.flaskapp.wsgi_dev:main" | ||||
|  | ||||
| [tool.poe.tasks] | ||||
| clean = """ | ||||
|     rm -rf | ||||
|        ./**/__pycache__ | ||||
|        ./**/worblehat.sqlite | ||||
| """ | ||||
|  | ||||
| # Migration related | ||||
| genmigration = "alembic revision --autogenerate -m" | ||||
| migrate = "alembic upgrade head" | ||||
| downmigrate = "alembic downgrade -1" | ||||
| # Be careful with cleanmigrations. If you run migrate a database and then | ||||
| # delete the migration file with this, there will be no easy way of downgrading | ||||
| cleanmigrations = "git clean -f worblehat/models/migrations/versions" | ||||
|  | ||||
|  | ||||
| [build-system] | ||||
| requires = ["poetry-core"] | ||||
| build-backend = "poetry.core.masonry.api" | ||||
|   | ||||
							
								
								
									
										56
									
								
								worblehat/models/migrations/env.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								worblehat/models/migrations/env.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| from alembic import context | ||||
| from flask import current_app | ||||
| from logging.config import fileConfig | ||||
| from sqlalchemy import engine_from_config | ||||
| from sqlalchemy import pool | ||||
|  | ||||
| from worblehat.models import Base | ||||
| from worblehat.services.config import Config | ||||
|  | ||||
| config = context.config | ||||
|  | ||||
| if config.config_file_name is not None: | ||||
|     fileConfig(config.config_file_name) | ||||
|  | ||||
| Config.load_configuration({}) | ||||
|  | ||||
| config.set_main_option('sqlalchemy.url', Config.db_string()) | ||||
|  | ||||
| # This will make sure alembic doesn't generate empty migrations | ||||
| # https://stackoverflow.com/questions/70203927/how-to-prevent-alembic-revision-autogenerate-from-making-revision-file-if-it-h | ||||
| def _process_revision_directives(context, revision, directives): | ||||
|     if config.cmd_opts.autogenerate: | ||||
|         script = directives[0] | ||||
|         if script.upgrade_ops.is_empty(): | ||||
|             directives[:] = [] | ||||
|             print('No changes in schema detected. Not generating migration.') | ||||
|  | ||||
| def run_migrations_online() -> None: | ||||
|     connectable = engine_from_config( | ||||
|         config.get_section(config.config_ini_section, {}), | ||||
|         prefix="sqlalchemy.", | ||||
|         poolclass=pool.NullPool, | ||||
|     ) | ||||
|  | ||||
|     with connectable.connect() as connection: | ||||
|         context.configure( | ||||
|             connection=connection, | ||||
|             target_metadata=Base.metadata, | ||||
|  | ||||
|             # Extended type checking with alembic when generating migrations | ||||
|             # https://alembic.sqlalchemy.org/en/latest/autogenerate.html#what-does-autogenerate-detect-and-what-does-it-not-detect | ||||
|             compare_type=True, | ||||
|  | ||||
|             # This is required for ALTER TABLE to work with sqlite. | ||||
|             # It should have no effect on postgreSQL | ||||
|             # https://alembic.sqlalchemy.org/en/latest/batch.html | ||||
|             render_as_batch=True, | ||||
|             process_revision_directives=_process_revision_directives, | ||||
|         ) | ||||
|  | ||||
|         with context.begin_transaction(): | ||||
|             context.run_migrations() | ||||
|  | ||||
| # We don't have any good reasons to generate raw sql migrations, | ||||
| # so the `run_migrations_offline` has been removed | ||||
| run_migrations_online() | ||||
							
								
								
									
										24
									
								
								worblehat/models/migrations/script.py.mako
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								worblehat/models/migrations/script.py.mako
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| """${message} | ||||
|  | ||||
| Revision ID: ${up_revision} | ||||
| Revises: ${down_revision | comma,n} | ||||
| Create Date: ${create_date} | ||||
|  | ||||
| """ | ||||
| from alembic import op | ||||
| import sqlalchemy as sa | ||||
| ${imports if imports else ""} | ||||
|  | ||||
| # revision identifiers, used by Alembic. | ||||
| revision = ${repr(up_revision)} | ||||
| down_revision = ${repr(down_revision)} | ||||
| branch_labels = ${repr(branch_labels)} | ||||
| depends_on = ${repr(depends_on)} | ||||
|  | ||||
|  | ||||
| def upgrade() -> None: | ||||
|     ${upgrades if upgrades else "pass"} | ||||
|  | ||||
|  | ||||
| def downgrade() -> None: | ||||
|     ${downgrades if downgrades else "pass"} | ||||
| @@ -0,0 +1,175 @@ | ||||
| """initial_migration | ||||
|  | ||||
| Revision ID: d51c7172d2f2 | ||||
| Revises:  | ||||
| Create Date: 2023-05-06 17:46:39.230122 | ||||
|  | ||||
| """ | ||||
| from alembic import op | ||||
| import sqlalchemy as sa | ||||
|  | ||||
|  | ||||
| # revision identifiers, used by Alembic. | ||||
| revision = 'd51c7172d2f2' | ||||
| down_revision = None | ||||
| branch_labels = None | ||||
| depends_on = None | ||||
|  | ||||
|  | ||||
| def upgrade() -> None: | ||||
|     # ### commands auto generated by Alembic - please adjust! ### | ||||
|     op.create_table('Author', | ||||
|     sa.Column('uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('name', sa.Text(), nullable=False), | ||||
|     sa.PrimaryKeyConstraint('uid', name=op.f('pk_Author')) | ||||
|     ) | ||||
|     with op.batch_alter_table('Author', schema=None) as batch_op: | ||||
|         batch_op.create_index(batch_op.f('ix_Author_name'), ['name'], unique=True) | ||||
|  | ||||
|     op.create_table('Bookcase', | ||||
|     sa.Column('description', sa.Text(), nullable=True), | ||||
|     sa.Column('uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('name', sa.Text(), nullable=False), | ||||
|     sa.PrimaryKeyConstraint('uid', name=op.f('pk_Bookcase')) | ||||
|     ) | ||||
|     with op.batch_alter_table('Bookcase', schema=None) as batch_op: | ||||
|         batch_op.create_index(batch_op.f('ix_Bookcase_name'), ['name'], unique=True) | ||||
|  | ||||
|     op.create_table('Category', | ||||
|     sa.Column('description', sa.Text(), nullable=True), | ||||
|     sa.Column('uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('name', sa.Text(), nullable=False), | ||||
|     sa.PrimaryKeyConstraint('uid', name=op.f('pk_Category')) | ||||
|     ) | ||||
|     with op.batch_alter_table('Category', schema=None) as batch_op: | ||||
|         batch_op.create_index(batch_op.f('ix_Category_name'), ['name'], unique=True) | ||||
|  | ||||
|     op.create_table('Language', | ||||
|     sa.Column('iso639_1_code', sa.String(length=2), nullable=False), | ||||
|     sa.Column('uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('name', sa.Text(), nullable=False), | ||||
|     sa.PrimaryKeyConstraint('uid', name=op.f('pk_Language')) | ||||
|     ) | ||||
|     with op.batch_alter_table('Language', schema=None) as batch_op: | ||||
|         batch_op.create_index(batch_op.f('ix_Language_iso639_1_code'), ['iso639_1_code'], unique=True) | ||||
|         batch_op.create_index(batch_op.f('ix_Language_name'), ['name'], unique=True) | ||||
|  | ||||
|     op.create_table('MediaType', | ||||
|     sa.Column('description', sa.Text(), nullable=True), | ||||
|     sa.Column('uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('name', sa.Text(), nullable=False), | ||||
|     sa.PrimaryKeyConstraint('uid', name=op.f('pk_MediaType')) | ||||
|     ) | ||||
|     with op.batch_alter_table('MediaType', schema=None) as batch_op: | ||||
|         batch_op.create_index(batch_op.f('ix_MediaType_name'), ['name'], unique=True) | ||||
|  | ||||
|     op.create_table('BookcaseShelf', | ||||
|     sa.Column('description', sa.Text(), nullable=True), | ||||
|     sa.Column('row', sa.SmallInteger(), nullable=False), | ||||
|     sa.Column('column', sa.SmallInteger(), nullable=False), | ||||
|     sa.Column('fk_bookcase_uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('uid', sa.Integer(), nullable=False), | ||||
|     sa.ForeignKeyConstraint(['fk_bookcase_uid'], ['Bookcase.uid'], name=op.f('fk_BookcaseShelf_fk_bookcase_uid_Bookcase')), | ||||
|     sa.PrimaryKeyConstraint('uid', name=op.f('pk_BookcaseShelf')), | ||||
|     sa.UniqueConstraint('column', 'fk_bookcase_uid', 'row', name=op.f('uq_BookcaseShelf_column')) | ||||
|     ) | ||||
|     op.create_table('BookcaseItem', | ||||
|     sa.Column('isbn', sa.String(), nullable=False), | ||||
|     sa.Column('owner', sa.String(), nullable=False), | ||||
|     sa.Column('amount', sa.SmallInteger(), nullable=False), | ||||
|     sa.Column('fk_media_type_uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('fk_bookcase_shelf_uid', sa.Integer(), nullable=True), | ||||
|     sa.Column('fk_language_uid', sa.Integer(), nullable=True), | ||||
|     sa.Column('uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('name', sa.Text(), nullable=False), | ||||
|     sa.ForeignKeyConstraint(['fk_bookcase_shelf_uid'], ['BookcaseShelf.uid'], name=op.f('fk_BookcaseItem_fk_bookcase_shelf_uid_BookcaseShelf')), | ||||
|     sa.ForeignKeyConstraint(['fk_language_uid'], ['Language.uid'], name=op.f('fk_BookcaseItem_fk_language_uid_Language')), | ||||
|     sa.ForeignKeyConstraint(['fk_media_type_uid'], ['MediaType.uid'], name=op.f('fk_BookcaseItem_fk_media_type_uid_MediaType')), | ||||
|     sa.PrimaryKeyConstraint('uid', name=op.f('pk_BookcaseItem')) | ||||
|     ) | ||||
|     with op.batch_alter_table('BookcaseItem', schema=None) as batch_op: | ||||
|         batch_op.create_index(batch_op.f('ix_BookcaseItem_isbn'), ['isbn'], unique=True) | ||||
|         batch_op.create_index(batch_op.f('ix_BookcaseItem_name'), ['name'], unique=True) | ||||
|  | ||||
|     op.create_table('BookcaseItemBorrowing', | ||||
|     sa.Column('username', sa.String(), nullable=False), | ||||
|     sa.Column('start_time', sa.DateTime(), nullable=False), | ||||
|     sa.Column('end_time', sa.DateTime(), nullable=False), | ||||
|     sa.Column('delivered', sa.Boolean(), nullable=False), | ||||
|     sa.Column('fk_bookcase_item_uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('uid', sa.Integer(), nullable=False), | ||||
|     sa.ForeignKeyConstraint(['fk_bookcase_item_uid'], ['BookcaseItem.uid'], name=op.f('fk_BookcaseItemBorrowing_fk_bookcase_item_uid_BookcaseItem')), | ||||
|     sa.PrimaryKeyConstraint('uid', name=op.f('pk_BookcaseItemBorrowing')) | ||||
|     ) | ||||
|     with op.batch_alter_table('BookcaseItemBorrowing', schema=None) as batch_op: | ||||
|         batch_op.create_index(batch_op.f('ix_BookcaseItemBorrowing_fk_bookcase_item_uid'), ['fk_bookcase_item_uid'], unique=False) | ||||
|  | ||||
|     op.create_table('BookcaseItemBorrowingQueue', | ||||
|     sa.Column('username', sa.String(), nullable=False), | ||||
|     sa.Column('entered_queue_time', sa.DateTime(), nullable=True), | ||||
|     sa.Column('should_notify_user', sa.Boolean(), nullable=True), | ||||
|     sa.Column('fk_bookcase_item_uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('uid', sa.Integer(), nullable=False), | ||||
|     sa.ForeignKeyConstraint(['fk_bookcase_item_uid'], ['BookcaseItem.uid'], name=op.f('fk_BookcaseItemBorrowingQueue_fk_bookcase_item_uid_BookcaseItem')), | ||||
|     sa.PrimaryKeyConstraint('uid', name=op.f('pk_BookcaseItemBorrowingQueue')) | ||||
|     ) | ||||
|     with op.batch_alter_table('BookcaseItemBorrowingQueue', schema=None) as batch_op: | ||||
|         batch_op.create_index(batch_op.f('ix_BookcaseItemBorrowingQueue_fk_bookcase_item_uid'), ['fk_bookcase_item_uid'], unique=False) | ||||
|  | ||||
|     op.create_table('Item_Author', | ||||
|     sa.Column('fk_item_uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('fk_author_uid', sa.Integer(), nullable=False), | ||||
|     sa.ForeignKeyConstraint(['fk_author_uid'], ['Author.uid'], name=op.f('fk_Item_Author_fk_author_uid_Author')), | ||||
|     sa.ForeignKeyConstraint(['fk_item_uid'], ['BookcaseItem.uid'], name=op.f('fk_Item_Author_fk_item_uid_BookcaseItem')), | ||||
|     sa.PrimaryKeyConstraint('fk_item_uid', 'fk_author_uid', name=op.f('pk_Item_Author')) | ||||
|     ) | ||||
|     op.create_table('Item_Category', | ||||
|     sa.Column('fk_item_uid', sa.Integer(), nullable=False), | ||||
|     sa.Column('fk_category_uid', sa.Integer(), nullable=False), | ||||
|     sa.ForeignKeyConstraint(['fk_category_uid'], ['Category.uid'], name=op.f('fk_Item_Category_fk_category_uid_Category')), | ||||
|     sa.ForeignKeyConstraint(['fk_item_uid'], ['BookcaseItem.uid'], name=op.f('fk_Item_Category_fk_item_uid_BookcaseItem')), | ||||
|     sa.PrimaryKeyConstraint('fk_item_uid', 'fk_category_uid', name=op.f('pk_Item_Category')) | ||||
|     ) | ||||
|     # ### end Alembic commands ### | ||||
|  | ||||
|  | ||||
| def downgrade() -> None: | ||||
|     # ### commands auto generated by Alembic - please adjust! ### | ||||
|     op.drop_table('Item_Category') | ||||
|     op.drop_table('Item_Author') | ||||
|     with op.batch_alter_table('BookcaseItemBorrowingQueue', schema=None) as batch_op: | ||||
|         batch_op.drop_index(batch_op.f('ix_BookcaseItemBorrowingQueue_fk_bookcase_item_uid')) | ||||
|  | ||||
|     op.drop_table('BookcaseItemBorrowingQueue') | ||||
|     with op.batch_alter_table('BookcaseItemBorrowing', schema=None) as batch_op: | ||||
|         batch_op.drop_index(batch_op.f('ix_BookcaseItemBorrowing_fk_bookcase_item_uid')) | ||||
|  | ||||
|     op.drop_table('BookcaseItemBorrowing') | ||||
|     with op.batch_alter_table('BookcaseItem', schema=None) as batch_op: | ||||
|         batch_op.drop_index(batch_op.f('ix_BookcaseItem_name')) | ||||
|         batch_op.drop_index(batch_op.f('ix_BookcaseItem_isbn')) | ||||
|  | ||||
|     op.drop_table('BookcaseItem') | ||||
|     op.drop_table('BookcaseShelf') | ||||
|     with op.batch_alter_table('MediaType', schema=None) as batch_op: | ||||
|         batch_op.drop_index(batch_op.f('ix_MediaType_name')) | ||||
|  | ||||
|     op.drop_table('MediaType') | ||||
|     with op.batch_alter_table('Language', schema=None) as batch_op: | ||||
|         batch_op.drop_index(batch_op.f('ix_Language_name')) | ||||
|         batch_op.drop_index(batch_op.f('ix_Language_iso639_1_code')) | ||||
|  | ||||
|     op.drop_table('Language') | ||||
|     with op.batch_alter_table('Category', schema=None) as batch_op: | ||||
|         batch_op.drop_index(batch_op.f('ix_Category_name')) | ||||
|  | ||||
|     op.drop_table('Category') | ||||
|     with op.batch_alter_table('Bookcase', schema=None) as batch_op: | ||||
|         batch_op.drop_index(batch_op.f('ix_Bookcase_name')) | ||||
|  | ||||
|     op.drop_table('Bookcase') | ||||
|     with op.batch_alter_table('Author', schema=None) as batch_op: | ||||
|         batch_op.drop_index(batch_op.f('ix_Author_name')) | ||||
|  | ||||
|     op.drop_table('Author') | ||||
|     # ### end Alembic commands ### | ||||
		Reference in New Issue
	
	Block a user