What I have here is my Account table and my settings table. Basically, there are many settings to one account and I plan on being able to input those settings with GraphQL using relay. Unfortunately, it throws the following error during yarn
relay:
ERROR:
GraphQLParser: Unknown field `maxAllowedRecords` on type `AccountObject`. Source: document `CreateAccountMutation` file: `mutations/CreateAccountMutation.js`.
maxAllowedRecords is not a field in Account object but rather a setting in the settings table that is related to a particular account object. I have the SQLAlchemy below:
class Account(Base):
__tablename__ = 'accounts'
id = Column(Integer, primary_key=True)
raw_id = Column('id', Integer, primary_key=True)
name = Column(String(255), nullable=False)
num_licenses = Column(Integer, nullable=False)
import_records_limit = Column(Integer, nullable=False)
max_failed_logins = Column(Integer, nullable=False)
status = Column(Integer, nullable=False)
employee_lists = relationship('EmployeeList')
users = relationship('User')
policies = relationship("Policy", secondary=accounts_policies, back_populates="accounts")
settings = relationship('AccountSetting')
class AccountSetting(Base):
__tablename__ = 'account_settings'
id = Column(Integer, primary_key=True)
account = relationship('Account')
account_id = Column(Integer, ForeignKey('accounts.id'))
name = Column(String(30))
value = Column(String(1000))
Here is the account mutation method
class CreateAccountMutation(graphene.Mutation):
class Arguments:
name = graphene.String(required=True)
num_licenses = graphene.Int(required=True)
import_records_limit = graphene.Int(required=True)
status = graphene.Int(required=True)
max_failed_logins = graphene.Int(required=True)
account_type = graphene.String(required=False)
max_allowed_records = graphene.String(required=False)
password_expiry = graphene.String(required=False)
account_type = graphene.String(required=False)
reinstated_notifications = graphene.String(required=False)
saml_only = graphene.String(required=False)
access_ip_range = graphene.String(required=False)
account = graphene.Field(lambda: AccountObject)
def mutate(self, info, **kwargs):
settings = []
for name, value in kwargs.items():
if name not in baseproperties:
settings.append(AccountSetting(name=name,value=value))
account = Account(name=kwargs.get('name'), num_licenses=kwargs.get('num_licenses'),
import_records_limit=kwargs.get('import_records_limit'), status=kwargs.get('status'),
max_failed_logins=kwargs.get('max_failed_logins'), settings=settings, date_created=datetime.utcnow())
db_session.add(account)
db_session.commit()
return CreateAccountMutation(account=account)
As you can see here, the additional properties passed that are not in the base properties will be placed in the settings as AccountSetting objects. This works with graphiQL:
mutation {
createAccount(name: "Red Cross", numLicenses: 76, importRecordsLimit: 50000, maxFailedLogins: 20, status: 1, maxAllowedRecords: "50", passwordExpiry: "90", accountType: "fullservice", reinstatedNotifications: "1", samlOnly: "0", accessIpRange: "Test Rangate") {
account {
name
settings {
name
value
}
}
}
}
But this mutation file doesn't compile:
const mutation = graphql`
mutation CreateAccountMutation(
$name: String!, $numLicenses: Int!, $importRecordsLimit: Int!, $status: Int!
$maxFailedLogins: Int!, $maxAllowedRecords: String!, $passwordExpiry: String!,
$accountType: String!, $reinstatedNotifications: String!, $samlOnly: String!, $accessIpRange: String!
) {
createAccount( name: $name, numLicenses: $numLicenses, importRecordsLimit: $importRecordsLimit, status: $status,
maxFailedLogins: $maxFailedLogins, maxAllowedRecords: $maxAllowedRecords, passwordExpiry: $passwordExpiry,
accountType: $accountType, reinstatedNotifications: $reinstatedNotifications, samlOnly: $samlOnly, accessIpRange: $accessIpRange
) {
account {
name
numLicenses
importRecordsLimit
status
maxFailedLogins
maxAllowedRecords
passwordExpiry
accountType
reinstatedNotifications
samlOnly
accessIpRange
}
}
}
`;
export default (
name,num_licenses,import_records_limit,status,
maxFailedLogins,maxAllowedRecords,passwordExpiry,
accountType,reinstatedNotifications,samlOnly,
accessIpRange, callback) => {
const variables = {
name,
num_licenses,
import_records_limit,
status,
maxFailedLogins,
maxAllowedRecords,
passwordExpiry,
accountType,
reinstatedNotifications,
samlOnly,
accessIpRange,
}
commitMutation(
environment,
{
mutation,
variables,
onCompleted: () => {
callback()
},
onError: err => console.error(err),
},
)
}
Am I doing something wrong here? Is there another way? A 'correct' way to approach this problem?