SQL expression element expected, got <sqlalchemy.sql.dml.Insert object at 0x7fd887828e80>

  fastapi, python, python-3.x, sqlalchemy

I have a table of Attribute and AttributeValue. An attribute can have many values. This is how the design looks like between those table

class Attribute(Base):
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String(255), nullable=False)
    slug = Column(String, index=True, unique=True)
    value_required = Column(Boolean, default=False)
    attribute_values = relationship("AttributeValue", back_populates="attribute")
    attribute_products = relationship("AttributeProduct", back_populates="attribute")
    attributevariant = relationship("AttributeVariant", back_populates="attribute")


class AttributeValue(Base):
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String(255), nullable=False)
    slug = Column(String, index=True, unique=True)
    attribute_id = Column(Integer, ForeignKey("attribute.id"))
    attribute = relationship("Attribute", back_populates="attribute_values")
    assigned_product_attribute_values = relationship(
        "AssignedProductAttributeValue", back_populates="attribute_value"
    )

I need to create an api for creating attribute with values as well if provided. This is how I am trying to do

async def check_values_are_unique(db, attribute_value, attribute):
    # get the list of slugs of particular attribute.
    # alternative of django values_list in sqlalchemy
    existing_values = await db.execute(select(attribute.values.slug).distinct()).all()
    for value_data in attribute_value:
        slug = slugify(value_data.title)
        if slug in existing_values:
            msg = "Value %s already exists within this attribute." % value_data["name"]
            # raise validaton error
            raise HTTPException(
                status_code=404,
                detail=msg,
            )

    new_slugs = [slugify(value_data.title) for value_data in attribute_value]
    if len(set(new_slugs)) != len(new_slugs):
        raise HTTPException(
            status_code=404,
            detail="Provided values are not unique.",
        )



async def resolve_create_attribute(db, data):
    try:
        clean_attributes = await validate_slug_and_generate_if_needed(
            db, Attribute, "title", data
        )  # clean_attributes AttributeCreateInput(title='Material', slug='material', values=[AttributeValueCreateInput(title='Cotton', value='cotton')], value_required=True, is_variant_only=False)
    except HTTPException:
        raise HTTPException(
            status_code=404,
            detail="slug is required",
        )
    values_input = data.values
    attribute_qs = Attribute.__table__.select().where(
        Attribute.__table__.c.title == data.title
    )
    attribute_exists = await db.fetch_one(query=attribute_qs)
    if attribute_exists:
        return Error(
            code="ATTRIBUTE_ALREADY_EXIST",
            message=f"Attribute with title {data.title} already exist",
        )
    else:
        # create an instance of attribute
        attribute_input = data.__dict__
        del attribute_input["values"]
        attribute = Attribute.__table__.insert().values(**attribute_input)
        print("attribute instance", attribute)
        # attribute_id = await db.execute(query) # create at last
        for val in values_input:
            setattr(val, "slug", slugify(val.title))
            attribute_value = AttributeValue.__table__.insert().values(
                **val.__dict__, attribute=attribute
            )
        print("attribute_value", attribute_value)
        check_values_are_unique(db, values_input, attribute)
        # NOW SAVE ATTRIBUTE AND ATTRIBTUEVALUE IN DB
        # response_payload = {**data.__dict__, "id": attribute_id}

    return []

I want to understand the flow/steps to save attribute once there is no any validation or uniqueness issue and save attribute value if it has only no any validation or uniqueness issue. There are two things to consider here attribute and attribute value in same api so I am confused.

How can I save both attribute and attribute values only after validation and uniqueness check? For now, the way I am doing is giving me an error

SQL expression element expected, got <sqlalchemy.sql.dml.Insert object
at 0x7fd887828e80>.

Note: I am using encode/database for async database and data I get is in dataclass format. This is how I get data

AttributeCreateInput(title=’Material’, slug=’material’,
values=[AttributeValueCreateInput(title=’Cotton’, value=’cotton’)],
value_required=True)

Source: Python-3x Questions

LEAVE A COMMENT