Open loicknuchel opened 9 months ago
Looking a bit more at the API I found I could use the JSON parser to generate a Database
:
const db: Database = (new Parser(undefined)).parse(JSON.stringify({...}), 'json')
It seems the JSON parser takes a RawDatabase
type, which is better but comes back to the same issue with the Table
model for example (can't build it, at least for now).
So I tried to export to JSON and then import:
const dbmb = `...`
const db: Database = (new Parser(undefined)).parse(dbml, 'dbmlv2')
const json: string = ModelExporter.export(db, 'json', false)
const db2: Database = (new Parser(undefined)).parse(json, 'json')
const generated = ModelExporter.export(db2, 'dbml', false)
But this fails when parsing the JSON, on the 4th line, with Can't find table "null"."posts"
.
Looks like the JSON output is not a valid JSON input :disappointed:
Seems that the relations don't work well on JSON, they fail both with and without schema.
Is there somewhere a documentation with the expected JSON structure for the Parser
?
In the RawDatabase
I see there is both schemas
(with tables inside) and tables
directly at the root. How does it work? Should I duplicate tables in both?
Edit: In investigated more and succedeed to make it work when the relation is not in the same schema as tables (maybe linked to looking for tables before adding them?). This DBML is working:
Table s1.users {
id integer [primary key]
name varchar
}
Table s2.posts {
id int [pk]
author integer
}
Ref: s1.users.id < s2.posts.author
It works because the relation is cross schema and then put inside the public
one.
If both tables are in the same schema, the relation will be inside as well and it fails.
Hi @loicknuchel
Can you help provide the JSON that failed initially (the one that give error Can't find table "null"."posts"
). We'll take a look into this.
I used the example from your documentation: https://dbml.dbdiagram.io/docs/#take-a-look-at-an-example-below Here is my full code:
test('https://github.com/holistics/dbml/issues/514', () => {
const content = `Table users {
id integer
username varchar
role varchar
created_at timestamp
}
Table posts {
id integer [primary key]
title varchar
body text [note: 'Content of the post']
user_id integer
created_at timestamp
}
Ref: posts.user_id > users.id // many-to-one`
const dbFromDbml = (new Parser(undefined)).parse(content, 'dbmlv2')
const json: string = ModelExporter.export(dbFromDbml, 'json', false)
console.log('json', json)
const dbFromJson = (new Parser(undefined)).parse(json, 'json')
console.log('json parsed!')
const generated = ModelExporter.export(dbFromJson, 'dbml', false)
console.log('dbml generated', generated)
})
It fails when trying to parse the json
: (new Parser(undefined)).parse(json, 'json')
with the error:
Can't find table "null"."posts"
Here is the printed JSON:
{
"schemas": [{
"name": "public",
"note": "Default Public Schema",
"tables": [{
"name": "users",
"alias": null,
"note": null,
"fields": [
{"name": "id", "type": {"schemaName": null, "type_name": "integer", "args": null}, "unique": false, "pk": false, "note": null},
{"name": "username", "type": {"schemaName": null, "type_name": "varchar", "args": null}, "unique": false, "pk": false, "note": null},
{"name": "role", "type": {"schemaName": null, "type_name": "varchar", "args": null}, "unique": false, "pk": false, "note": null},
{"name": "created_at", "type": {"schemaName": null, "type_name": "timestamp", "args": null}, "unique": false, "pk": false, "note": null}
],
"indexes": []
}, {
"name": "posts",
"alias": null,
"note": null,
"fields": [
{"name": "id", "type": {"schemaName": null, "type_name": "integer", "args": null}, "unique": false, "pk": true, "not_null": false, "note": null, "increment": false},
{"name": "title", "type": {"schemaName": null, "type_name": "varchar", "args": null}, "unique": false, "pk": false, "note": null},
{"name": "body", "type": {"schemaName": null, "type_name": "text", "args": null}, "unique": false, "pk": false, "not_null": false, "note": "Content of the post", "increment": false},
{"name": "user_id", "type": {"schemaName": null, "type_name": "integer", "args": null}, "unique": false, "pk": false, "note": null},
{"name": "created_at", "type": {"schemaName": null, "type_name": "timestamp", "args": null}, "unique": false, "pk": false, "note": null}
],
"indexes": []
}],
"enums": [],
"tableGroups": [],
"refs": [{
"name": null,
"endpoints": [
{"schemaName": null, "tableName": "posts", "fieldNames": ["user_id"], "relation": "*"},
{"schemaName": null, "tableName": "users", "fieldNames": ["id"], "relation": "1"}
]
}]
}]
}
If the relation is not in the same schema as tables, it works.
BTW, it also fails with any TableGroup
^^
But I'm only using the JSON parser to build a Database
class from my own structure as I couldn't create it directly :disappointed:
Is it an intended usage to generate DBML from JavaScript? (coming with my own data)
Hi, First, thank you for this project and the libraries <3
I have an object representing my db and I'm looking to generate DBML from it. Looking at https://dbml.dbdiagram.io/js-module/#class-modelexporter I see I can generate DBML using:
My issue is, I don't know how to generate a
database
value withDatabase
type :disappointed:In the example it's build using the parser but I don't have DBML as input.
I saw the
Database
class is exported here: dbml-core/src/model_structure/database.js, and I tried to import it using:But it gives me the error:
Cannot find module '@dbml/core/types/model_structure/database' from 'src/dbml.ts'
And when I try:
I got the error:
Cannot find module '@dbml/core/model_structure/database' or its corresponding type declarations.
Do you have any idea how I can configure TypeScript to match modules and type definitions or how I can create a Database class? I think it would be nice to export the models in
model_structure
in theindex.js
, what do you think? Also, I don't know the difference between a Database and a NormalizedDatabase, is there any explanation somewhere?Thanks!