I am trying to create a Model using SQLAlchemy which has one specific column that is generated through a relationship of type 1..1. Which means "One Request has only one Description".
The way it is stored on SQL, is like this:
- On REQUEST (Table TQB), there is one field called
TQB_CODMSSwith the Description code. - On DESCRIPTIONS (Table SYP), there is two fields, one called
YP_CAMPOwhich takes the valueTQB_CODMSS, and another one calledYP_CHAVE, which takes the valueTQB_CODMSShas on REQUEST table.
So, a SELECT for this would be something like:
-- List descriptions fro all REQUESTs.
-- Description is saved on SYP010 Table and the 1..1 relationship is done using TQB_CODMSS (Table Requests), YP_CHAVE and YP_CAMPO (Table Descriptions).
SELECT
-- Select the TEXT Column only.
SYP.YP_TEXTO AS request_description
FROM
TQB010 REQUESTS
-- On SYP: YP_CHAVE has the column from REQUESTs TQB_CODMSS, and YP_CAMPO has the code stored on TQB_CODMSS on REQUESTs Table.
LEFT JOIN SYP010 SYP ON SOLICITACOES_DE_SERVICO.TQB_CODMSS = SYP.YP_CHAVE;
-- TQB010.TQB_CODMSS --> Column Value goes to SYP010.YP_CHAVE
-- SYP010.YP_CAMPO = TQB010.TQB_CODMSS
It works, lists ALL descriptions for my requests.
What I want to do is to do this using SQLAlchemy, using it's One-to-One Syntax. Here is the things I am taking into consideration:
- There is no Description Column on REQUESTs Table, so doing
request_description: Mapped[str] = mapped_column("TQB_DESCSS", db_sql.String)will not work. - The relationship is made using only TQB_CODMSS field (Which is the code used as Primary Key for
YP_CHAVEon SYP Table.)
I tried doing like this:
- First I Mapped the Models
from dataclasses import dataclass
from sqlalchemy.orm import relationship, Mapped, mapped_column
from sqlalchemy import ForeignKey
from db_context import db_sql
@dataclass
class Description(db_sql.Model):
"""
Represents a description of a request for service.
The relationship is done using the TQB_CODMSS field, which is the primary key of the SYP010 table (YP_CAMPO).
"""
__tablename__ = 'SYP010'
description_id: Mapped[str] = mapped_column(ForeignKey("YP_CHAVE"), db_sql.String, primary_key=True)
description_relationship_field: Mapped[str] = mapped_column("YP_CAMPO", db_sql.String, nullable=False)
description_text: Mapped[str] = mapped_column("YP_DESC", db_sql.String, nullable=False)
@dataclass
class RequestDescription(db_sql.Model):
"""
Represents a request for service comment.
It has a code value which serves as a primary key for the SYP010 table (YP_CHAVE).
"""
__tablename__ = 'TQB010'
request_description: Mapped[str] = relationship("Description", back_populates="RequestDescription")
request_description_id: Mapped[str] = mapped_column("TQB_CODMSS", db_sql.String, primary_key=True)
- Secondly I tried executing and creating the query which would bring all descriptions of Requests:
@staticmethod
def get_descriptions():
"""
List all descriptions of requests for service.
It's the equivalent for the following SQL:
-- Trago só a descrição da Solicitação de Serviço.
-- A descrição da S.S. é salva na tabela SYP010 e vinculada pelo campo da S.S. TQB_CODMSS e o campo da SYP010 YP_CHAVE.
SELECT
SYP.YP_TEXTO AS solicitacao_descricao
FROM
TQB010 SOLICITACOES_DE_SERVICO
-- Na SYP: YP_CHAVE é o código do TQB_CODMSS, e a YP_CAMPO contém o valor da COLUNA que ele vai puxar o código (TQB_CODMSS).
LEFT JOIN SYP010 SYP ON SOLICITACOES_DE_SERVICO.TQB_CODMSS = SYP.YP_CHAVE;
-- Resumindo:
-- TQB010.TQB_CODMSS = SYP010.YP_CHAVE
-- SYP010.YP_CAMPO = TQB010.TQB_CODMSS
"""
# 1. Create the Query only.
descriptions_list = RequestDescription.query(Solicitacao.solicitacao_descricao)
# 2. Executes the Query.
descriptions_list = descriptions_list.all()
print("Descriptions: ", descriptions_list)
But as soon I start the server, I am getting some errors from SQL Alchemy, on the Models mapping:
description_id: Mapped[str] = mapped_column(ForeignKey("YP_CHAVE"), db_sql.String, primary_key=True)
sqlalchemy.exc.ArgumentError: 'SchemaItem' object, such as a 'Column' or a 'Constraint' expected, got <class 'sqlalchemy.sql.sqltypes.String'>
Can someone help me? Please.
My Project uses Marshmallow SQLAlchemy, SQLAlchemy and Flask SQLAlchemy. The objective is to map the descriptions and then make a route in Flask available for querying data using the model objects.