I have the following schema:
from flask_marshmallow import Marshmallow
ma = Marshmallow(app)
class TicketSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = db_models.TicketModel
load_instance = True
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field_name, field in self.fields.items():
field.required = False
TicketModel is a sqlalchemy db model reflected with automap_base. The primary key of the table is the column TicketId. When I try to load a dictionary that contains the primary key:
data = {
"TicketId" :"123"
}
TicketSchema().load(data)
It gives me
File "/lib/python3.10/site-packages/marshmallow_sqlalchemy/load_instance_mixin.py", line 60, in get_instance
return self.session.get(self.opts.model, filters)
AttributeError: 'DummySession' object has no attribute 'get'
But when I try to load data that has any other field defined in the schema, it works. This error only happens when I try to load a field that is defined as a Primary Key.
EDIT: I included the DDL of the table I am reflecting from the database and how the sqlalchemy model is set up.
CREATE TABLE Ticket (
TicketId varchar(100) NOT NULL,
Requestor varchar(20) NOT NULL,
Description varchar(MAX) NULL,
CONSTRAINT Tickets_Rules_PK PRIMARY KEY (TicketId)
);
and the sqlalchemy model:
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.ext.automap import automap_base
engine = create_engine(
f'mssql+pymssql://{user_sql}:{password_sql}@db', echo=False)
metadata = MetaData(schema=Config.SCHEMA) # This is a string
# Define the list of table names to reflect
table_names = Config.TABLES_TO_REFLECT # This is a list of strings
# Reflect tables
tables = {table_name:Table(table_name, metadata, autoload_with=engine) for table_name in table_names}
# Automap base
Base = automap_base(metadata=metadata)
Base.prepare()
# Access the model from Base
TicketModel = Base.classes.Ticket
2nd EDIT Packages I am using:
marshmallow-sqlalchemy==1.0.0
SQLAlchemy==2.0.30
flask-marshmallow==1.2.1
It's not clear from the docs (or alternatively, it's implicitly assumed), but you need to supply a sqla_session
session factory attribute to the schema's Meta
inner class.
...
from sqlalchemy import orm
...
Session = orm.scoped_session(orm.sessionmaker(engine))
...
class TicketSchema(ma.SQLAlchemyAutoSchema):
class Meta:
sqla_session = Session # <- this
model = TicketModel
load_instance = True