2 votes

Graphene_sqlalchemy et flask-sqlalchemy ne sont pas d'accord sur ce qui constitue un modèle SQLAlchemy valide ?

Je joue avec Flask, Graphene et je rencontre un problème. Considérons ce qui suit.

Le modèle project.model.site :

from project import db
from project.models import user
from datetime import datetime

class Site(db.Model):
    __tablename__ = 'sites'
    id = db.Column(db.Integer(), primary_key=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    name = db.Column(db.String(50))
    desc = db.Column(db.Text())
    location_lon = db.Column(db.String(50))
    location_lat = db.Column(db.String(50))
    creation_date = db.Column(db.DateTime(), default=datetime.utcnow())
    users = db.relationship(
        user,
        backref=db.backref('users',
                        uselist=True,
                        cascade='delete,all'))

Le schéma du modèle (project.schemas.site_schema)

from graphene_sqlalchemy import SQLAlchemyObjectType
from project.models import site as site_model
import graphene

class SiteAttributes:
    owner_id = graphene.ID(description="Site owners user.id")
    name = graphene.String(description="Site Name")
    desc = graphene.String(description="Site description")
    location_lon = graphene.String(description="Site Longitude")
    location_lat = graphene.String(description="Site Latitude")
    creation_date = graphene.DateTime(description="Site Creation Date")

class Site(SQLAlchemyObjectType, SiteAttributes):
    """Site node."""
    class Meta:
        model = site_model
        interfaces = (graphene.relay.Node,)

et enfin le schéma principal à travers lequel je prévois d'exposer l'api GraphQL (project.schemas.schema))

from graphene_sqlalchemy import SQLAlchemyConnectionField
import graphene
from project.schemas import site_schema, trade_schema, user_schema

class Query(graphene.ObjectType):
    """Query objects for GraphQL API."""

    node = graphene.relay.Node.Field()
    user = graphene.relay.Node.Field(user_schema.User)
    userList = SQLAlchemyConnectionField(user_schema.User)
    site = graphene.relay.Node.Field(site_schema.Site)
    siteList = SQLAlchemyConnectionField(site_schema.Site)
    trade = graphene.relay.Node.Field(trade_schema.Trade)
    tradeList = SQLAlchemyConnectionField(trade_schema.Trade)

schema = graphene.Schema(query=Query)

Si je charge le modèle en tant que tel au démarrage, tout va bien. Les migrations ont lieu, l'application fonctionne parfaitement. Par contre, si je charge le modèle via le schéma, l'application échoue avec le message suivant :

AssertionError: You need to pass a valid SQLAlchemy Model in Site.Meta, received "<module 'project.models.site' from '/vagrant/src/project/models/site.py'>".

J'ai initialisé SQLAlchemy avec flask_sqlalchemy. Ce qui m'amène à me demander si le modèle créé n'est pas considéré comme un modèle SQLAlchemy valide ? Ou est-ce que je fais une erreur de base que je ne vois pas. Je suppose que c'est la seconde hypothèse.

4voto

jwodder Points 13193

D'après le message d'erreur, il semble que project.models.site (importé dans le deuxième extrait avec from project.models import site as site_model ) est un module Python plutôt qu'une sous-classe de db.Model ou similaire. Vous vouliez peut-être importer Site (majuscules) au lieu de site ?

1voto

Vevmesteren Points 86

Le fait de fixer des paquets aux classes m'a finalement orienté dans la bonne direction. Il s'avère que le problème est plus profond que cela. Et le seul moyen de l'atteindre était de lire les exceptions cachées.

J'ai d'abord veillé à ce que les modèles réels soient chargés plutôt que les modules. Merci beaucoup pour cela @jwodder

En fin de compte, cette https://github.com/graphql-python/graphene-sqlalchemy/issues/121 a fini par m'orienter dans la bonne direction. En vérifiant les messages d'exception, j'ai trouvé une solution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X