Skip to content

Commit

Permalink
💪 Sentence fetching from database working
Browse files Browse the repository at this point in the history
Turns out painful grinding of the docs was adequate to solve this immediate problem.

This required an overhaul to now the models were being automaped.  This overhaul will be applied to the rest of the tables in subsequent commits.

Sentence fetching only works on infinitives and correctness at this point, but adding the remaining features shouldn't prove to be much of a problem later.
  • Loading branch information
beverage committed Oct 23, 2024
1 parent a0ead11 commit 4628adc
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 55 deletions.
7 changes: 7 additions & 0 deletions src/dbtest/database/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import enum

from sqlalchemy import inspect

def object_as_dict(obj):
return {
c.key: getattr(obj, c.key)
for c in inspect(obj).mapper.column_attrs
}

class DatabaseStringEnum(enum.Enum):

def __str__(self):
return self.name
6 changes: 3 additions & 3 deletions src/dbtest/dbtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from .sentences.create import create_random_problem_with_delay, create_random_problem
from .sentences.create import create_random_sentence, create_sentence
from .sentences.database import get_sentence
from .sentences.database import get_random_sentence
from .sentences.utils import problem_formatter

from .verbs.get import download_verb, get_verb, get_random_verb
Expand Down Expand Up @@ -87,8 +87,8 @@ async def sentence():
@click.option('-q', '--quantity', required=False, default=1)
@sentence_options
async def get(quantity: int, **kwargs):
result = await get_sentence(quantity, **kwargs)
print(problem_formatter([result.first()]))
result = await get_random_sentence(quantity, **kwargs)
print(problem_formatter(result))

@sentence.command('new')
@click.option('-q', '--quantity', required=False, default=1)
Expand Down
4 changes: 4 additions & 0 deletions src/dbtest/sentences/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ async def create_sentence(verb_infinitive: str,
sentence.content = response_json["sentence"]
sentence.translation = response_json["translation"]

# The Promptable extension requires the full base enum name so we have to do this here. That can be changed later.
sentence.tense = str(sentence.tense)
sentence.pronoun = str(sentence.pronoun)

sentence.negation = response_json["negation"]
sentence.direct_object = response_json["direct_object"]
sentence.indirect_pronoun = response_json["indirect_pronoun"]
Expand Down
43 changes: 22 additions & 21 deletions src/dbtest/sentences/database.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@

from ..database.engine import AsyncSession, get_async_session, Base
from .models import Pronoun, Tense, DirectObject, IndirectPronoun, Negation, Sentence
from ..database.engine import AsyncSession, get_async_session

from sqlalchemy import inspect
from sqlalchemy import select

import logging
from .models import Pronoun, DirectObject, IndirectPronoun, Negation, Sentence
from ..verbs.models import Tense

async def get_sentence(quantity: int,
verb_infinitive: str,
pronoun: Pronoun = Pronoun.first_person, # Pronoun and tense will remain both random
tense: Tense = Tense.present, # and correct for now. These values will be
direct_object: DirectObject = DirectObject.none, # ignored.
indirect_pronoun: IndirectPronoun = IndirectPronoun.none,
negation: Negation = Negation.none,
is_correct: bool = True): # This cannot be guaranteed until the AI has responded.
from sqlalchemy import select
from sqlalchemy.sql.expression import func

async def get_random_sentence(
quantity: int,
verb_infinitive: str,
pronoun: Pronoun = Pronoun.first_person, # Pronoun and tense will remain both random
tense: Tense = Tense.present, # and correct for now. These values will be
direct_object: DirectObject = DirectObject.none, # ignored.
indirect_pronoun: IndirectPronoun = IndirectPronoun.none,
negation: Negation = Negation.none,
is_correct: bool = True): # This cannot be guaranteed until the AI has responded.

async with get_async_session() as session:

stmt = select(Sentence).where(Sentence.infinitive == verb_infinitive).limit(quantity)

logging.info(str(stmt))

sentence: Sentence = (
await session.execute(stmt)
stmt = (
select(Sentence)
.where(Sentence.infinitive == verb_infinitive)
.where(Sentence.is_correct == is_correct)
.order_by(func.random())
.limit(quantity)
)

return sentence
return await session.scalars(stmt)

async def save_sentence(sentence: Sentence):
async with get_async_session() as session:
Expand Down
42 changes: 12 additions & 30 deletions src/dbtest/sentences/models.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
from enum import auto
import sqlalchemy
from sqlalchemy import Enum, Column, String, Boolean, quoted_name
from sqlalchemy.dialects.postgresql import ENUM as SQLAlchemyEnum

from dbtest.database.engine import async_engine
from dbtest.database.metadata import Base, metadata
from sqlalchemy.ext.asyncio import AsyncAttrs

from dbtest.database.metadata import Base
from dbtest.database.utils import DatabaseStringEnum

from dbtest.utils.prompt_enum import PromptEnum
from dbtest.verbs.models import Tense

class Pronoun(PromptEnum):
class Pronoun(DatabaseStringEnum, PromptEnum):
first_person = auto()
second_person = auto()
third_person = auto()
first_person_plural = auto()
second_person_plural = auto()
third_person_plural = auto()

class DirectObject(PromptEnum):
class DirectObject(DatabaseStringEnum, PromptEnum):
none = auto()
masculine = auto()
feminine = auto()
plural = auto()
random = auto()

class IndirectPronoun(PromptEnum):
class IndirectPronoun(DatabaseStringEnum, PromptEnum):
none = auto()
masculine = auto()
feminine = auto()
plural = auto()
random = auto()

class ReflexivePronoun(PromptEnum):
class ReflexivePronoun(DatabaseStringEnum, PromptEnum):
none = auto()
first_person = auto()
second_person = auto()
third_person = auto()

class Negation(PromptEnum):
class Negation(DatabaseStringEnum, PromptEnum):
none = auto()
pas = auto()
jamais = auto()
Expand All @@ -47,22 +46,5 @@ class Negation(PromptEnum):
encore = auto()
random = auto()

sentence_table = sqlalchemy.Table("sentences", metadata,
Column("id", sqlalchemy.Integer, primary_key=True),
# Column('group_id', ForeignKey('verb_groups.id')),
Column('infinitive', String(), nullable=False),
Column('auxiliary', String(), nullable=False),
Column('pronoun', Enum(Pronoun), nullable=False, default=Pronoun.first_person),
Column('tense', Enum(Tense), nullable=False, default=Tense.present),
Column('direct_object', SQLAlchemyEnum(DirectObject, name=quoted_name('direct_object', True)), nullable=False, default=DirectObject.none),
Column('indirect_pronoun', SQLAlchemyEnum(IndirectPronoun, name=quoted_name('indirect_pronoun', True)), nullable=False, default=IndirectPronoun.none),
Column('reflexive_pronoun', SQLAlchemyEnum(ReflexivePronoun, name=quoted_name('reflexive_pronoun', True)), nullable=False, default=ReflexivePronoun.none),
Column('negation', Enum(Negation), nullable=False, default=Negation.none),
Column('content', String(), nullable=False),
Column('translation', String(), nullable=False),
Column('is_correct', Boolean(), nullable=False, default=True),
extend_existing=False
)

class Sentence(Base): # pylint: disable=too-few-public-methods
__table__ = sqlalchemy.Table('sentences', metadata, autoload=True, autoload_with=async_engine)
class Sentence(AsyncAttrs, Base): # pylint: disable=too-few-public-methods
__tablename__ = "sentences"
4 changes: 3 additions & 1 deletion src/dbtest/verbs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

from dbtest.database.engine import async_engine
from dbtest.database.metadata import Base, metadata
from dbtest.database.utils import DatabaseStringEnum

from dbtest.utils.prompt_enum import PromptEnum

class Tense(PromptEnum):
class Tense(DatabaseStringEnum, PromptEnum):
present = auto()
passe_compose = auto()
imparfait = auto()
Expand Down

0 comments on commit 4628adc

Please sign in to comment.