Additional Built-In Queries
Now let's add 2 more queries to our table. This time we will do something a little more advanced than just
a basic SELECT
or INSERT
.
Add the lines highlighted below:
todo_items.si | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
We'll start with line 29:
26 27 28 29 |
|
This might look very a little weird, but it is actually really simple to understand. This simply creates a function that selects all the records from the Todo_Item table, for a specified TodoList_ID. In other words, this function will generate SQL similar to
1 2 3 4 5 6 7 8 9 |
|
Run ./generate_jportal.sh
again. Remember to run it from the terminal inside VSCode!
Search for a class named DB_ToDo_ItemSelectByTodoList_ID
. You should see the following:
@dataclass
class DB_ToDo_ItemSelectByTodoList_ID:
#Outputs
ID: int
ItemName: str
ItemDescription: str
LastUpdated: datetime
@classmethod
def get_statement(cls
, TodoList_ID: int
) -> TextAsFrom:
class _ret:
sequence = "default," #postgres uses default for sequences
output = " OUTPUT (ID,ItemName,ItemDescription,LastUpdated)"
tail = " RETURNING ID ItemName ItemDescription LastUpdated"
#session.bind.dialect.name
statement = sa.text(
f"/* PROC ToDoList_App.ToDo_Item.SelectByTodoList_ID */"
f"select"
f" ID"
f", ItemName"
f", ItemDescription"
f", LastUpdated"
f" from ToDoList_App.ToDo_Item"
f" where TodoList_ID = :TodoList_ID")
text_statement = statement.columns(ID=sa.types.Integer,
ItemName=db_types.NonNullableString,
ItemDescription=sa.types.Text,
LastUpdated=sa.types.DateTime,
)
text_statement = text_statement.bindparams(TodoList_ID=TodoList_ID,
)
return text_statement
@classmethod
def execute(cls, session: Session, TodoList_ID: int
) -> List['DB_ToDo_ItemSelectByTodoList_ID']:
params = process_bind_params(session, [sa.types.Integer,
], [TodoList_ID,
])
PROC UpdateBy ItemName SET ItemDescription res = session.execute(cls.get_statement(*params))
recs = res.fetchall()
return process_result_recs(DB_ToDo_ItemSelectByTodoList_ID, session, [sa.types.Integer,
db_types.NonNullableString,
sa.types.Text,
sa.types.DateTime,
], recs)
Now look at line 31:
31 |
|
You should start to see the pattern by now. We are creating an update statement that will update the ItemDescription for a given ItemName.
Run ./generate_jportal.sh
and open the db_ToDo_Item.py
file again.
Now search for a class named DB_ToDo_ItemUpdateByItemDescription
.
Look closely at the line highlighted below.
@dataclass
class DB_ToDo_ItemUpdateByItemDescription:
@classmethod
def get_statement(cls
, ItemDescription: str
, LastUpdated: datetime
, ItemName: str
) -> TextAsFrom:
class _ret:
sequence = "default," #postgres uses default for sequences
output = ""
tail = ""
#session.bind.dialect.name
statement = sa.text(
f"/* PROC ToDoList_App.ToDo_Item.UpdateByItemDescription */"
f"update ToDoList_App.ToDo_Item"
f" set"
f" ItemDescription = :ItemDescription"
f", LastUpdated = :LastUpdated"
f" where ItemName = :ItemName")
text_statement = statement.columns()
text_statement = text_statement.bindparams(ItemDescription=ItemDescription,
LastUpdated=LastUpdated,
ItemName=ItemName,
)
return text_statement
@classmethod
def execute(cls, session: Session, ItemDescription: str
, LastUpdated: datetime
, ItemName: str
) -> None:
params = process_bind_params(session, [sa.types.Text,
sa.types.DateTime,
db_types.NonNullableString,
], [ItemDescription,
LastUpdated,
ItemName,
])
res = session.execute(cls.get_statement(*params))
res.close()
What's this? We specified that we wanted to update the ItemDescription. But the generated code is also updating
the LastUpdated
field! Why is it doing that? Is the generation wrong?
No, actually this is a feature built into JPortal2. Look again at the table definition, specifically the column
definition for LastUpdated. You will notice the columntype is specified as TIMESTAMP
.
TIMESTAMP is a special type. When you specify a TIMESTAMP column, you are telling JPortal that you want this column to be updated every time you update the record. JPortal's generated INSERT statements will automatically put the current time into this column, as will the normal UPDATE. In this case, because we are doing a custom UPDATE, JPortal generates an input field that we must set when we call the function.