neo4j-graphql-js icon indicating copy to clipboard operation
neo4j-graphql-js copied to clipboard

Create database constraints and indexes from type defs

Open johnymontana opened this issue 5 years ago • 13 comments

johnymontana avatar Nov 11 '18 02:11 johnymontana

Hi @johnymontana! Will this feature make throwing Unique property violation errors possible? Is there currently any workaround for creating this kind of constraints from the graphql schema? Thanks a lot!

ghost avatar Nov 12 '18 12:11 ghost

@stradivari96 yes, that's the idea for this feature. Probably driven by a @unique schema directive or similar.

Currently you'll have to manually run the Cypher statements to create uniqueness constraints. So for example if you have

type User {
  userid: ID!
  name: String
}

You would want to run this Cypher statement:

CREATE CONSTRAINT (u:User) ASSERT u.userid IS UNIQUE;

to create a uniqueness constraint.

johnymontana avatar Nov 12 '18 22:11 johnymontana

@johnymontana any progress on the indexes?

appinteractive avatar Jan 08 '19 11:01 appinteractive

Bump - this is very important!

ulfgebhardt avatar May 29 '19 18:05 ulfgebhardt

Also curious as to where this stand on the roadmap.

Phylodome avatar May 29 '19 22:05 Phylodome

This is something you’d want to do only once, or anytime the schema changes, probably not as frequently as on application startup. It’s more like a database initialization step. We were recently thinking this might make sense to have as part of a command line utility.

A good first step would be a separate export that generates the Cypher statements, scanning typedefs for @unique directive

johnymontana avatar Jul 10 '19 16:07 johnymontana

@johnymontana @appinteractive @Phylodome @ulfgebhardt Was able to implement this by leveraging the neo4jAssertConstraints method from require('neo4j-graphql-binding')

const { makeAugmentedSchema } = require('neo4j-graphql-js');
const { neo4jAssertConstraints } = require('neo4j-graphql-binding');

export async function getAugmentedSchema(driver) {
  // Execute cypher constraints on server start
  await neo4jAssertConstraints({
    typeDefs,
    driver,
    log: true,
  });

  // Make augmented schema
  return makeAugmentedSchema({
    resolvers,
    typeDefs
  });
}

rphansen91 avatar Jul 26 '19 19:07 rphansen91

@roschaefer

ulfgebhardt avatar Jul 26 '19 22:07 ulfgebhardt

FYI, the neo4j-graphql-binding package doesn't seem to support Neo4j 4.0. It uses an older {param} syntax in its Cypher queries, which was removed in 4.0, and throws an error by default:

Neo4jError: The old parameter syntax `{param}` is no longer supported. Please use `$param` instead (line 1, column 25 (offset: 24))
"CALL apoc.schema.assert({indexes}, {constraints}) YIELD label, key, unique, action RETURN { label: label, key: key, unique: unique, action: action }"

jamescoletti avatar Mar 18 '20 02:03 jamescoletti

any movement on this feature? not sure how i will manage unique constraints without something like this.

agnewp avatar May 12 '20 21:05 agnewp

+1. I wrongly created a similar feature request on the neo4j-graphql repo wanting to post it here.

type User { userid: ID! name: String } You would want to run this Cypher statement:

CREATE CONSTRAINT (u:User) ASSERT u.userid IS UNIQUE; to create a uniqueness constraint.

Actually, shouldn't it be an existence constraint instead of uniqueness?

type User {
  id: ID!
  name: String!
  avatar_url: String
}

You wouldn't want some non-nullable fields to be unique.

CREATE CONSTRAINT ON (u:User)
ASSERT EXISTS (u.id, u.name)

Also from Neo4j > Administration > 5.4. Constraints:

Unique node property constraints, node property existence constraints and relationship property existence constraints are only available in Neo4j Enterprise Edition.

So the plugin should check for the edition, add the constraint if enterprise, else raise a warning that the graphql schema isn't reliable.

AdrienLemaire avatar May 22 '20 02:05 AdrienLemaire

Another bump here!

Related: The excerpt from the link above is misleading. It seems that "unique node property constraint" is the only type of constraint available in the community edition. The others are all in enterprise. "unique node property constraint" doesn't have the green "enterprise edition" box next to it, and I did try it in a community edition neo4j succesfully.

ahmedhosny avatar Jul 17 '20 18:07 ahmedhosny

https://github.com/neo4j-graphql/neo4j-graphql-js/issues/608

michaeldgraham avatar May 02 '21 04:05 michaeldgraham