diff --git a/docs/changelog.md b/docs/changelog.md index 6f61851..df78b13 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format. +## [0.4.2] -- 2023-06-27 +- Added validation of question mark in name and tag +- Fixed description and name in config file +- Fixed preserving order of columns in database + ## [0.4.1] -- 2023-06-09 - Fixed project.update function diff --git a/manual_tests.py b/manual_tests.py index 32a5a61..84d0fe0 100644 --- a/manual_tests.py +++ b/manual_tests.py @@ -58,8 +58,13 @@ def upload_sample_pep_to_db(connection: pepdbagent.PEPDatabaseAgent): prj = peppy.Project( "/home/bnt4me/virginia/repos/pepdbagent/tests/data/namespace1/basic/project_config.yaml" ) +fgf = prj.to_dict() +rr = prj.to_dict(extended=True) con.project.create(project=prj, namespace="dog_namespace", name="testttt", tag="test1", overwrite=True) + +pr = con.project.get(namespace="dog_namespace", name="testttt", tag="test1", raw=True) +pr con.project.exists(namespace="dog_namespace", name="testttt", tag="test1") @@ -114,4 +119,7 @@ def upload_sample_pep_to_db(connection: pepdbagent.PEPDatabaseAgent): con.project.update(update_dict={"is_private": False}, namespace="dog_namespace", name="testttt", tag="test1") -dell = con.project.delete(namespace="dog_namespace", name="testttt", tag="test1") \ No newline at end of file +dell = con.project.delete(namespace="dog_namespace", name="testttt", tag="test1") + + +from pydantic import BaseModel \ No newline at end of file diff --git a/pepdbagent/_version.py b/pepdbagent/_version.py index 3d26edf..df12433 100644 --- a/pepdbagent/_version.py +++ b/pepdbagent/_version.py @@ -1 +1 @@ -__version__ = "0.4.1" +__version__ = "0.4.2" diff --git a/pepdbagent/db_utils.py b/pepdbagent/db_utils.py index e127ffb..30ad926 100644 --- a/pepdbagent/db_utils.py +++ b/pepdbagent/db_utils.py @@ -13,7 +13,7 @@ select, TIMESTAMP, ) -from sqlalchemy.dialects.postgresql import JSONB +from sqlalchemy.dialects.postgresql import JSON from sqlalchemy.engine import URL, create_engine from sqlalchemy.exc import ProgrammingError from sqlalchemy.ext.compiler import compiles @@ -39,9 +39,9 @@ def compile_bigserial_pg(type_, compiler, **kw): return "BIGSERIAL" -@compiles(JSONB, POSTGRES_DIALECT) +@compiles(JSON, POSTGRES_DIALECT) def compile_jsonb_pg(type_, compiler, **kw): - return "JSONB" + return "JSON" class Base(DeclarativeBase): @@ -67,7 +67,7 @@ class Projects(Base): name: Mapped[str] = mapped_column(primary_key=True) tag: Mapped[str] = mapped_column(primary_key=True) digest: Mapped[str] = mapped_column(String(32)) - project_value: Mapped[dict] = mapped_column(JSONB, server_default=FetchedValue()) + project_value: Mapped[dict] = mapped_column(JSON, server_default=FetchedValue()) private: Mapped[bool] number_of_samples: Mapped[int] submission_date: Mapped[datetime.datetime] diff --git a/pepdbagent/models.py b/pepdbagent/models.py index 9b094c8..24c225e 100644 --- a/pepdbagent/models.py +++ b/pepdbagent/models.py @@ -110,6 +110,12 @@ def value_must_be_lowercase(cls, v): return v.lower() return v + @validator("tag", "name") + def value_should_not_contain_question(cls, v): + if "?" in v: + return ValueError("Question mark (?) is prohibited in name and tag.") + return v + class Config: extra = Extra.forbid allow_population_by_field_name = True diff --git a/pepdbagent/modules/project.py b/pepdbagent/modules/project.py index 39cc87e..25a874f 100644 --- a/pepdbagent/modules/project.py +++ b/pepdbagent/modules/project.py @@ -190,12 +190,14 @@ def create( :return: None """ proj_dict = project.to_dict(extended=True) + proj_dict["_config"]["description"] = project.description namespace = namespace.lower() if name: name = name.lower() proj_name = name proj_dict["name"] = name + proj_dict["_config"]["name"] = project.name elif proj_dict["name"]: proj_name = proj_dict["name"].lower() else: @@ -381,8 +383,11 @@ def __create_update_dict(update_values: UpdateItems) -> dict: update_final = UpdateModel() if update_values.project_value is not None: + proj_dict = update_values.project_value.to_dict(extended=True) + proj_dict["_config"]["description"] = proj_dict["description"] + proj_dict["_config"]["name"] = proj_dict["name"] update_final = UpdateModel( - project_value=update_values.project_value.to_dict(extended=True), + project_value=proj_dict, name=update_values.project_value.name, digest=create_digest(update_values.project_value.to_dict(extended=True)), last_update_date=datetime.datetime.now(datetime.timezone.utc),