[UPD] Added BookTag

This commit is contained in:
2026-02-13 14:29:39 +01:00
parent dc819b1674
commit 75c295ce4b
6 changed files with 112 additions and 21 deletions

View File

@@ -1,6 +1,7 @@
from .base import Base from .base import Base
from .env import Env from .env import Env
#from .tag import Tag from .tag import Tag
from .path import Path from .path import Path
from .library import Library from .library import Library
from .book import Book from .book import Book
from .book_tag import BookTag

View File

@@ -1,6 +1,6 @@
from typing import List from typing import List
from typing import Optional from typing import Optional
from sqlalchemy import String, ForeignKey from sqlalchemy import String, ForeignKey, Integer
from sqlalchemy.orm import Mapped from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
@@ -10,17 +10,22 @@ from .base import Base
class Book(Base): class Book(Base):
__tablename__ = "book" __tablename__ = "book"
id: Mapped[int] = mapped_column(primary_key=True) id: Mapped[int] = mapped_column(primary_key=True)
hash: Mapped[str] = mapped_column(String(255)) hash: Mapped[Optional[str]] = mapped_column(String(255))
file_name: Mapped[str] = mapped_column(String(255)) file_name: Mapped[Optional[str]] = mapped_column(String(65656))
file_path: Mapped[str] = mapped_column(String(65656)) file_path: Mapped[Optional[str]] = mapped_column(String(65656))
name: Mapped[str] = mapped_column(String(255)) name: Mapped[str] = mapped_column(String(65656))
publisher: Mapped[str] = mapped_column(String(255)) publisher: Mapped[Optional[str]] = mapped_column(String(65656))
notes: Mapped[str] = mapped_column(String(65656)) notes: Mapped[Optional[str]] = mapped_column(String(65656))
classification: Mapped[int] = mapped_column(primary_key=True) classification: Mapped[Optional[int]] = mapped_column(Integer)
library_id: Mapped[int] = mapped_column(ForeignKey("library.id")) library_id: Mapped[int] = mapped_column(ForeignKey("library.id"))
library: Mapped[int] = relationship("Library", back_populates="books") library: Mapped[int] = relationship("Library", back_populates="books")
tags: Mapped[List["BookTag"]] = relationship(
back_populates="book", cascade="all, delete-orphan"
)
def __repr__(self) -> str: def __repr__(self) -> str:
return f"Book(id={self.id!r}, name={self.name!r}, publisher={self.publisher!r}," \ return f"Book(id={self.id!r}, name={self.name!r}, publisher={self.publisher!r}, " \
" notes={self.notes!r}, classification={self.classification!r})" f"notes={self.notes!r}, classification={self.classification!r}), " \
f"hash={self.hash!r}, file_name={self.file_name}, file_path={self.file_path})"

View File

@@ -0,0 +1,21 @@
from typing import List
from typing import Optional
from sqlalchemy import String, ForeignKey
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship
from .base import Base
class BookTag(Base):
__tablename__ = "book_tag_relation"
id: Mapped[int] = mapped_column(primary_key=True)
book_id: Mapped[int] = mapped_column(ForeignKey("book.id"))
book: Mapped[int] = relationship("Book", back_populates="tags")
tag_id: Mapped[int] = mapped_column(ForeignKey("tag.id"))
tag: Mapped[int] = relationship("Tag", back_populates="books")
def __repr__(self) -> str:
return f"BookTag(id={self.id!r}, book_id={self.book_id!r}, tag_id={self.tag_id!r}"

View File

@@ -25,5 +25,9 @@ class Library(Base):
back_populates="library", cascade="all, delete-orphan" back_populates="library", cascade="all, delete-orphan"
) )
tags: Mapped[List["Tag"]] = relationship(
back_populates="library", cascade="all, delete-orphan"
)
def __repr__(self) -> str: def __repr__(self) -> str:
return f"Library(id={self.id!r}, name={self.name!r}, notes={self.notes!r}" return f"Library(id={self.id!r}, name={self.name!r}, notes={self.notes!r}"

View File

@@ -1,6 +1,6 @@
from typing import List from typing import List
from typing import Optional from typing import Optional
from sqlalchemy import String from sqlalchemy import String, ForeignKey
from sqlalchemy.orm import Mapped from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
@@ -12,10 +12,12 @@ class Tag(Base):
id: Mapped[int] = mapped_column(primary_key=True) id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(255)) name: Mapped[str] = mapped_column(String(255))
books: Mapped[List["Book"]] = relationship( books: Mapped[List["BookTag"]] = relationship(
back_populates="tags", cascade="all, delete-orphan" back_populates="tag", cascade="all, delete-orphan"
) )
library_id: Mapped[int] = mapped_column(ForeignKey("library.id"))
library: Mapped[int] = relationship("Library", back_populates="tags")
def __repr__(self) -> str: def __repr__(self) -> str:
return f"Book(id={self.id!r}, name={self.name!r}, publisher={self.publisher!r}," \ return f"Tag(id={self.id!r}, name={self.name!r})"
" notes={self.notes!r}, classification={self.classification!r})"

View File

@@ -4,10 +4,11 @@ import unittest
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from app.api.actions import install from app.api.actions import install
from app.api.cruds.library import create, read from app.api.cruds.library import create, read, update
from app.schema.library import Library, Path, Env from app.schema.library import Library, Path, Env, Book, Tag, BookTag
import logging import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class TestDB(unittest.TestCase): class TestDB(unittest.TestCase):
@@ -16,6 +17,14 @@ class TestDB(unittest.TestCase):
os.environ["DEV_URIA_BIBLIOGAME_CONFIG_DB"] = "sqlite:///" os.environ["DEV_URIA_BIBLIOGAME_CONFIG_DB"] = "sqlite:///"
os.environ["DEV_URIA_BIBLIOGAME_DEBUG"] = "true" os.environ["DEV_URIA_BIBLIOGAME_DEBUG"] = "true"
self.engine = install() self.engine = install()
self.tags = [
Tag(
name="Foo"
),
Tag(
name="Bar"
)
]
self.library = Library( self.library = Library(
name="Library Test", name="Library Test",
notes="My duckling library test", notes="My duckling library test",
@@ -29,7 +38,18 @@ class TestDB(unittest.TestCase):
key="ENVIRONMENT_VARIABLE", key="ENVIRONMENT_VARIABLE",
value="Clearly an environment variable" value="Clearly an environment variable"
) )
],
books=[
Book(
name="Test book",
tags=[
BookTag(
tag=self.tags[0]
)
] ]
),
],
tags=self.tags
) )
self.Session = sessionmaker(bind=self.engine) self.Session = sessionmaker(bind=self.engine)
self.session = self.Session() self.session = self.Session()
@@ -66,6 +86,44 @@ class TestDB(unittest.TestCase):
self.assertEqual(library.envs[0].key, "ENVIRONMENT_VARIABLE") self.assertEqual(library.envs[0].key, "ENVIRONMENT_VARIABLE")
self.assertEqual(library.envs[0].value, "Clearly an environment variable") self.assertEqual(library.envs[0].value, "Clearly an environment variable")
def test_read_book(self):
library = read(self.session, 1)
book = library.books[0]
logger.debug(f"BOOK: {book}")
self.assertEqual(book.name, self.library.books[0].name)
self.assertEqual(book.name, "Test book")
def test_read_tags(self):
library = read(self.session, 1)
tags = library.tags
self.assertEqual(tags, self.library.tags)
self.assertEqual(tags, self.tags)
self.assertEqual(str(tags[0]), str(self.tags[0]))
self.assertEqual(tags[0].name, self.tags[0].name)
self.assertEqual(tags[0].name, "Foo")
self.assertEqual(str(tags[1]), str(self.tags[1]))
self.assertEqual(tags[1].name, self.tags[1].name)
self.assertEqual(tags[1].name, "Bar")
def test_read_book_tags(self):
library = read(self.session, 1)
book = library.books[0]
tags = library.tags
logger.debug(f"BOOK TAGS: {book.tags}")
self.assertEqual(str(book.tags[0].tag), str(self.tags[0]))
self.assertEqual(str(book.tags[0].tag), str(tags[0]))
self.assertEqual(book.tags[0].tag.name, tags[0].name)
self.assertEqual(book.tags[0].tag.name, "Foo")
self.assertNotEqual(book.tags[0].tag.name, "Bar")
def test_update_name(self):
library = read(self.session, 1)
library.name = "Another Library"
update(self.session, library)
self.assertEqual(library.name, self.library.name)
self.assertNotEqual(library.name, "Library Test")
self.assertEqual(library.name, "Another Library")
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()