Fully implemented Django ORM for Database operations

tyler
tylerklane 2024-03-29 14:56:53 -04:00
parent 0d98ac8477
commit d1eceb19c9
12 changed files with 376 additions and 219 deletions

View File

View File

@ -1,12 +1,17 @@
import uuid
import os
import django
import sys
try:
from .config import Database
except ImportError:
from config import Database
current_script_path = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.join(current_script_path, '..', '..', '..')
sys.path.insert(0, os.path.abspath(project_root))
from django.db import connection
os.environ.setdefault('DJANGO_SETTINGS_MODULE', "alttextbackend.settings")
django.setup()
from alttextbackend.data.postgres.models import Book
"""
@ -19,14 +24,6 @@ BOOKS DATABASE ATTRIBUTES
coverExt: str
"""
def createBookTable():
query = "CREATE TABLE books (id varchar(255) NOT NULL PRIMARY KEY, title varchar(255), size varchar(255), status varchar(255), numImages int, coverExt varchar(255));"
with connection.cursor() as cursor:
cursor.execute(query)
return cursor.fetchall()
def jsonifyBook(book: tuple):
return {
"id": book[0],
@ -39,37 +36,34 @@ def jsonifyBook(book: tuple):
def getBook(id: str):
db = Database()
query = "SELECT * FROM books WHERE id = %s"
params = (id,)
db.sendQuery(query, params)
book = db.fetchOne()
db.close()
return book
book_tuple = Book.objects.filter(id=id).values_list(
'id', 'title', 'size', 'status', 'numImages', 'coverExt', named=False
).first()
# Check if a book was found; if not, return None
if book_tuple is None:
return None
return book_tuple
def getBooks(titleQ: str = None, limit: int = None, skip: int = None):
db = Database()
params = []
query = "SELECT * FROM books"
books_query = Book.objects.all()
# Filter by title if a title query is provided
if titleQ:
lowerTitleQ = f"%{titleQ.lower()}%"
query += " WHERE LOWER(title) LIKE %s"
params.append(lowerTitleQ)
if limit is not None:
query += " LIMIT %s"
params.append(limit)
books_query = books_query.filter(title__icontains=titleQ)
# Apply limit and skip (offset) if provided
if skip is not None:
query += " OFFSET %s"
params.append(skip)
books_query = books_query[skip:] # Skip the first `skip` records
if limit is not None:
books_query = books_query[:limit] # Take `limit` records from the query set
db.sendQuery(query, params)
books = db.fetchAll()
db.close()
return books
# Execute the query and fetch the results
books = books_query.values_list('id', 'title', 'size', 'status', 'numImages', 'coverExt', flat=False)
return list(books)
def addBook(
@ -83,48 +77,30 @@ def addBook(
if id == None:
id = str(uuid.uuid4())
db = Database()
query = "INSERT INTO books (id, title, status, numimages, size, coverext) VALUES (%s, %s, %s, %s, %s, %s);"
params = (id, title, status, numImages, size, coverExt)
db.sendQuery(query, params)
db.commit()
db.close()
newBook = Book(
id=id,
title=title,
size=size,
numImages=numImages,
status=status,
coverExt=coverExt
)
newBook.save()
return getBook(id)
def deleteBook(id: str):
db = Database()
query = "DELETE FROM books WHERE id = %s"
params = (id,)
db.sendQuery(query, params)
db.commit()
db.close()
myBook = Book.objects.get(id=id)
myBook.delete()
def updateBook(id: str, title: str = None, status: str = None, coverExt: str = None):
db = Database()
update_fields = {}
if title is not None:
update_fields['title'] = title
if status is not None:
update_fields['status'] = status
if coverExt is not None:
update_fields['coverExt'] = coverExt
if title or status or coverExt:
params = []
query = "UPDATE books SET"
if title:
query += " title = %s,"
params.append(title)
if status:
query += " status = %s,"
params.append(status)
if coverExt:
query += " coverext = %s,"
params.append(coverExt)
query = query[:-1]
query += " WHERE id = %s"
params.append(id)
db.sendQuery(query, params)
db.commit()
db.close()
if update_fields:
Book.objects.filter(id=id).update(**update_fields)

View File

@ -1,7 +1,17 @@
try:
from .config import Database
except ImportError:
from config import Database
import sys
import os
import django
current_script_path = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.join(current_script_path, '..', '..', '..')
sys.path.insert(0, os.path.abspath(project_root))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', "alttextbackend.settings")
django.setup()
from alttextbackend.data.postgres.models import Image, Book
"""
IMAGE DATABASE ATTRIBUTES
@ -19,15 +29,6 @@ IMAGE DATABASE ATTRIBUTES
additionalContext: str
"""
def createImageTable():
db = Database()
query = "CREATE TABLE images (bookid varchar(255) NOT NULL, src varchar(255) NOT NULL, hash varchar(255), status varchar(255), alt varchar(1000), originalAlt varchar(1000), genAlt varchar(1000), genImageCaption varchar(1000), ocr varchar(1000), beforeContext varchar(2000), afterContext varchar(2000), additionalContext varchar(1000), CONSTRAINT PK_Image PRIMARY KEY (bookid, src), FOREIGN KEY (bookid) REFERENCES books(id) ON DELETE CASCADE);"
db.sendQuery(query)
db.commit()
db.close()
def jsonifyImage(image: tuple):
return {
"bookid": image[0],
@ -46,33 +47,39 @@ def jsonifyImage(image: tuple):
def getImageByBook(bookid: str, src: str):
db = Database()
query = "SELECT * FROM images WHERE bookid = %s AND src = %s"
params = (bookid, src)
db.sendQuery(query, params)
image = db.fetchOne()
db.close
return image
book = Book.objects.get(id=bookid)
image_tuple = Image.objects.filter(book=book, src=src).values_list(
'book_id', 'src', 'hash', 'status', 'alt', 'originalAlt',
'genAlt', 'genImageCaption', 'ocr', 'beforeContext',
'afterContext', 'additionalContext', named=False
).first()
# Check if an image was found; if not, return None
if image_tuple is None:
return None
return image_tuple
def getImagesByBook(bookid: str):
db = Database()
query = "SELECT * FROM images WHERE bookid = %s"
params = (bookid,)
db.sendQuery(query, params)
images = db.fetchAll()
db.close()
return images
book = Book.objects.get(id=bookid)
images_tuples = Image.objects.filter(book=book).values_list(
'book_id', 'src', 'hash', 'status', 'alt', 'originalAlt',
'genAlt', 'genImageCaption', 'ocr', 'beforeContext',
'afterContext', 'additionalContext', named=False
)
return list(images_tuples)
def getImagesByHash(hash: str):
db = Database()
query = "SELECT * FROM images WHERE hash = %s"
params = (hash,)
db.sendQuery(query, params)
images = db.fetchAll()
db.close()
return images
images_tuples = Image.objects.filter(hash=hash).values_list(
'book_id', 'src', 'hash', 'status', 'alt', 'originalAlt',
'genAlt', 'genImageCaption', 'ocr', 'beforeContext',
'afterContext', 'additionalContext', named=False
)
return list(images_tuples)
def addImage(
@ -89,53 +96,42 @@ def addImage(
afterContext: str = None,
additionalContext: str = None,
):
db = Database()
query = "INSERT INTO images (bookid, src, hash, status, alt, originalalt, genalt, genimagecaption, ocr, beforecontext, aftercontext, additionalcontext) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s);"
if status != "available" and status != "processing":
status = "available"
if alt is not None:
alt = alt[:1000]
if originalAlt is not None:
originalAlt = originalAlt[:1000]
if genAlt is not None:
genAlt = genAlt[:1000]
if genImageCaption is not None:
genImageCaption = genImageCaption[:1000]
if ocr is not None:
ocr = ocr[:1000]
if beforeContext is not None:
beforeContext = beforeContext[:2000]
if afterContext is not None:
afterContext = afterContext[:2000]
if additionalContext is not None:
additionalContext = additionalContext[:1000]
params = (
bookid,
src,
hash,
status,
alt,
originalAlt,
genAlt,
genImageCaption,
ocr,
beforeContext,
afterContext,
additionalContext,
status = status if status in ["available", "processing"] else "available"
# Truncate strings to their maximum allowed length based on the model's definitions
alt = alt[:1000] if alt is not None else None
originalAlt = originalAlt[:1000] if originalAlt is not None else None
genAlt = genAlt[:1000] if genAlt is not None else None
genImageCaption = genImageCaption[:1000] if genImageCaption is not None else None
ocr = ocr[:1000] if ocr is not None else None
beforeContext = beforeContext[:2000] if beforeContext is not None else None
afterContext = afterContext[:2000] if afterContext is not None else None
additionalContext = additionalContext[:1000] if additionalContext is not None else None
book_instance = Book.objects.get(id=bookid)
# Create and save the new Image instance
new_image = Image.objects.create(
book=book_instance,
src=src,
hash=hash,
status=status,
alt=alt,
originalAlt=originalAlt,
genAlt=genAlt,
genImageCaption=genImageCaption,
ocr=ocr,
beforeContext=beforeContext,
afterContext=afterContext,
additionalContext=additionalContext,
)
db.sendQuery(query, params)
db.commit()
db.close()
return getImageByBook(bookid, src)
return new_image
def deleteImage(bookid: str, src: str):
db = Database()
query = "DELETE FROM images WHERE bookid = %s AND src = %s;"
params = (bookid, src)
db.sendQuery(query, params)
db.commit()
db.close()
book = Book.objects.get(id=bookid)
Image.objects.filter(book=book, src=src).delete()
def updateImage(
@ -150,59 +146,25 @@ def updateImage(
afterContext: str = None,
additionalContext: str = None,
):
db = Database()
update_fields = {}
if status is not None:
update_fields['status'] = status
if alt is not None:
update_fields['alt'] = alt
if genAlt is not None:
update_fields['genAlt'] = genAlt
if genImageCaption is not None:
update_fields['genImageCaption'] = genImageCaption
if ocr is not None:
update_fields['ocr'] = ocr
if beforeContext is not None:
update_fields['beforeContext'] = beforeContext
if afterContext is not None:
update_fields['afterContext'] = afterContext
if additionalContext is not None:
update_fields['additionalContext'] = additionalContext
if (
status
or alt
or genAlt
or genImageCaption
or ocr
or beforeContext
or afterContext
or additionalContext
):
params = []
query = "UPDATE images SET"
if status:
query += " status = %s,"
params.append(status)
if alt:
query += " alt = %s,"
params.append(alt)
if genAlt:
query += " genalt = %s,"
params.append(genAlt)
if genImageCaption:
query += " genimagecaption = %s,"
params.append(genImageCaption)
if ocr:
query += " ocr = %s,"
params.append(ocr)
if beforeContext:
query += " beforecontext = %s,"
params.append(beforeContext)
if afterContext:
query += " aftercontext = %s,"
params.append(afterContext)
if additionalContext:
query += " additionalcontext = %s,"
params.append(additionalContext)
query = query[:-1]
query += " WHERE bookid = %s AND src = %s"
params.append(bookid)
params.append(src)
db.sendQuery(query, params)
db.commit()
db.close()
# Only execute the update if there are fields to update
if update_fields:
book = Book.objects.get(id=bookid)
Image.objects.filter(book=book, src=src).update(**update_fields)

View File

@ -0,0 +1,25 @@
# Generated by Django 5.0.3 on 2024-03-26 23:12
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Book',
fields=[
('id', models.CharField(max_length=255, primary_key=True, serialize=False)),
('title', models.CharField(blank=True, max_length=255, null=True)),
('size', models.CharField(blank=True, max_length=255, null=True)),
('status', models.CharField(blank=True, max_length=255, null=True)),
('num_images', models.IntegerField(blank=True, null=True)),
('cover_ext', models.CharField(blank=True, max_length=255, null=True)),
],
),
]

View File

@ -0,0 +1,35 @@
# Generated by Django 5.0.3 on 2024-03-27 20:32
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('postgres', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Image',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('src', models.CharField(max_length=255)),
('hash', models.CharField(blank=True, max_length=255, null=True)),
('status', models.CharField(blank=True, max_length=255, null=True)),
('alt', models.TextField(blank=True, null=True)),
('original_alt', models.TextField(blank=True, null=True)),
('gen_alt', models.TextField(blank=True, null=True)),
('gen_image_caption', models.TextField(blank=True, null=True)),
('ocr', models.TextField(blank=True, null=True)),
('before_context', models.TextField(blank=True, null=True)),
('after_context', models.TextField(blank=True, null=True)),
('additional_context', models.TextField(blank=True, null=True)),
('book', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='postgres.book')),
],
options={
'unique_together': {('book', 'src')},
},
),
]

View File

@ -0,0 +1,21 @@
# Generated by Django 5.0.3 on 2024-03-27 20:34
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('postgres', '0002_image'),
]
operations = [
migrations.AlterModelTable(
name='book',
table='book',
),
migrations.AlterModelTable(
name='image',
table='image',
),
]

View File

@ -0,0 +1,53 @@
# Generated by Django 5.0.3 on 2024-03-27 23:00
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('postgres', '0003_alter_book_table_alter_image_table'),
]
operations = [
migrations.RenameField(
model_name='book',
old_name='cover_ext',
new_name='coverExt',
),
migrations.RenameField(
model_name='book',
old_name='num_images',
new_name='numImages',
),
migrations.RenameField(
model_name='image',
old_name='additional_context',
new_name='additionalContext',
),
migrations.RenameField(
model_name='image',
old_name='after_context',
new_name='afterContext',
),
migrations.RenameField(
model_name='image',
old_name='before_context',
new_name='beforeContext',
),
migrations.RenameField(
model_name='image',
old_name='gen_alt',
new_name='genAlt',
),
migrations.RenameField(
model_name='image',
old_name='gen_image_caption',
new_name='genImageCaption',
),
migrations.RenameField(
model_name='image',
old_name='original_alt',
new_name='originalAlt',
),
]

View File

@ -0,0 +1,21 @@
# Generated by Django 5.0.3 on 2024-03-27 23:05
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('postgres', '0004_rename_cover_ext_book_coverext_and_more'),
]
operations = [
migrations.AlterModelTable(
name='book',
table='books',
),
migrations.AlterModelTable(
name='image',
table='images',
),
]

View File

@ -0,0 +1,36 @@
from django.db import models
class Book(models.Model):
id = models.CharField(max_length=255, primary_key=True)
title = models.CharField(max_length=255, blank=True, null=True)
size = models.CharField(max_length=255, blank=True, null=True)
status = models.CharField(max_length=255, blank=True, null=True)
numImages = models.IntegerField(null=True, blank=True)
coverExt = models.CharField(max_length=255, blank=True, null=True)
class Meta:
db_table = 'books'
def __str__(self):
return self.title
class Image(models.Model):
book = models.ForeignKey('Book', on_delete=models.CASCADE)
src = models.CharField(max_length=255)
hash = models.CharField(max_length=255, blank=True, null=True)
status = models.CharField(max_length=255, blank=True, null=True)
alt = models.TextField(blank=True, null=True)
originalAlt = models.TextField(blank=True, null=True)
genAlt = models.TextField(blank=True, null=True)
genImageCaption = models.TextField(blank=True, null=True)
ocr = models.TextField(blank=True, null=True)
beforeContext = models.TextField(blank=True, null=True)
afterContext = models.TextField(blank=True, null=True)
additionalContext = models.TextField(blank=True, null=True)
class Meta:
db_table = 'images'
unique_together = ('book', 'src')
def __str__(self):
return f"Image {self.src} of Book {self.book.id}"

View File

@ -1,16 +1,31 @@
import dotenv
from books import addBook, getBooks, getBook, updateBook
from books import addBook, getBooks, getBook, updateBook, deleteBook
from images import (
addImage,
getImagesByBook,
getImageByBook,
getImagesByHash,
updateImage,
deleteImage,
)
from config import Database
import os
import django
import sys
dotenv.load_dotenv()
#project_root = "/SeniorD/alt-text-backend"
#sys.path.insert(0, project_root)
# Set the Django settings module
#os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'alttextbackend.settings')
# Prepare the Django project for use
#django.setup()
"""
createBookTable = "CREATE TABLE books (id varchar(255) NOT NULL PRIMARY KEY, title varchar(255), size varchar(255), status varchar(255), numImages int, coverExt varchar(255));"
createImageTable = "CREATE TABLE images (bookid varchar(255) NOT NULL, src varchar(255) NOT NULL, hash varchar(255), status varchar(255), alt varchar(255), originalAlt varchar(255), genAlt varchar(255), genImageCaption varchar(255), ocr varchar(255), beforeContext varchar(255), afterContext varchar(255), additionalContext varchar(255), CONSTRAINT PK_Image PRIMARY KEY (bookid, src), FOREIGN KEY (bookid) REFERENCES books(id) ON DELETE CASCADE);"
@ -26,30 +41,40 @@ addBook(title="Harraoeu", size="300kb", numImages=25)
addBook(title="Hartter", size="300kb", numImages=25)
"""
# getBooks(titleQ="Harry Potter", limit=1, skip=2)
#print(getBooks())
#deleteBook('43198a6e-73ad-4e57-a2df-a7c9c7f8ce9a')
"""
addImage(
bookid="f1ac43cc-9f6d-4dc8-ac4f-aea0c4af5198",
src="sampleSrcMEOW",
bookid="845e7e66-860c-4df1-b64e-82c805c5cc3c",
src="sampleSrcMEOW2222",
hash="brown",
status="available",
genAlt="yeahhhh"
)
"""
# getImagesByBook("fa47d830-586a-485f-a579-67b33fd3eae3")
print(getImageByBook(bookid="845e7e66-860c-4df1-b64e-82c805c5cc3c", src="sampleSrcMEOW"))
#print(getBook("845e7e66-860c-4df1-b64e-82c805c5cc3c"))
#print(getImagesByBook("845e7e66-860c-4df1-b64e-82c805c5cc3c"))
#print(getImagesByHash("brown"))
"""
updateImage(
bookid="f1ac43cc-9f6d-4dc8-ac4f-aea0c4af5198",
bookid="845e7e66-860c-4df1-b64e-82c805c5cc3c",
src="sampleSrcMEOW",
status="bruh2",
status="bruh2234234",
beforeContext="before context be like",
)
"""
#deleteImage(bookid="845e7e66-860c-4df1-b64e-82c805c5cc3c", src="sampleSrcMEOW2222")
# updateBook(id="72950", title="Test Title Two", status="available")
#updateBook(id="845e7e66-860c-4df1-b64e-82c805c5cc3c", coverExt="your mother")
#print(getBooks())
db = Database()
# db.sendQuery("SELECT * FROM images;")

View File

@ -11,6 +11,8 @@ https://docs.djangoproject.com/en/4.2/ref/settings/
"""
from pathlib import Path
from dotenv import load_dotenv
load_dotenv()
import os
@ -39,6 +41,7 @@ INSTALLED_APPS = [
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"alttextbackend.data.postgres",
"rest_framework",
]