Implemented many to many relations
This commit is contained in:
parent
d59dedc106
commit
3418f15103
@ -4,6 +4,23 @@ namespace MycroForge.CLI.CodeGen;
|
|||||||
|
|
||||||
public partial class EntityLinker
|
public partial class EntityLinker
|
||||||
{
|
{
|
||||||
|
#region AssociationTable
|
||||||
|
|
||||||
|
private static readonly string[] AssociationTable =
|
||||||
|
[
|
||||||
|
"from sqlalchemy import Column, ForeignKey, Table",
|
||||||
|
"from db.entities.entity_base import EntityBase",
|
||||||
|
"",
|
||||||
|
"%left_entity%_%right_entity%_mapping = Table(",
|
||||||
|
"\t\"%left_entity%_%right_entity%_mapping\",",
|
||||||
|
"\tEntityBase.metadata,",
|
||||||
|
"\tColumn(\"%left_entity%_id\", ForeignKey(\"%left_table%.id\"), primary_key=True),",
|
||||||
|
"\tColumn(\"%right_entity%_id\", ForeignKey(\"%right_table%.id\"), primary_key=True),",
|
||||||
|
")"
|
||||||
|
];
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
private readonly ProjectContext _context;
|
private readonly ProjectContext _context;
|
||||||
private readonly string _left;
|
private readonly string _left;
|
||||||
private readonly string _right;
|
private readonly string _right;
|
||||||
@ -21,12 +38,12 @@ public partial class EntityLinker
|
|||||||
var right = await LoadEntity(_right);
|
var right = await LoadEntity(_right);
|
||||||
|
|
||||||
left.AppendColumn(
|
left.AppendColumn(
|
||||||
$"\t{right.FieldName}: Mapped[\"{right.ClassName}\"] = relationship(back_populates=\"{left.FieldName}\")"
|
$"\t{right.FieldName}: Mapped[\"{right.ClassName.Pascalize()}\"] = relationship(back_populates=\"{left.FieldName}\")"
|
||||||
);
|
);
|
||||||
|
|
||||||
right.AppendColumns([
|
right.AppendColumns([
|
||||||
$"\t{left.FieldName}_id: Mapped[int] = mapped_column(ForeignKey(\"{left.TableName}.id\"))",
|
$"\t{left.FieldName}_id: Mapped[int] = mapped_column(ForeignKey(\"{left.TableName}.id\"))",
|
||||||
$"\t{left.FieldName}: Mapped[\"{left.ClassName}\"] = relationship(back_populates=\"{right.FieldName}\")"
|
$"\t{left.FieldName}: Mapped[\"{left.ClassName.Pascalize()}\"] = relationship(back_populates=\"{right.FieldName}\")"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await _context.WriteFile(left.Path, left.Rewrite());
|
await _context.WriteFile(left.Path, left.Rewrite());
|
||||||
@ -39,11 +56,12 @@ public partial class EntityLinker
|
|||||||
var right = await LoadEntity(_right);
|
var right = await LoadEntity(_right);
|
||||||
|
|
||||||
left.Import(from: "typing", import: "List");
|
left.Import(from: "typing", import: "List");
|
||||||
left.AppendColumn($"\t{right.FieldName.Pluralize()}: Mapped[List[\"{right.ClassName}\"]] = relationship()");
|
left.AppendColumn(
|
||||||
|
$"\t{right.FieldName.Pluralize()}: Mapped[List[\"{right.ClassName.Pascalize()}\"]] = relationship()");
|
||||||
|
|
||||||
right.AppendColumns([
|
right.AppendColumns([
|
||||||
$"\t{left.FieldName}_id: Mapped[int] = mapped_column(ForeignKey(\"{left.TableName}.id\"))",
|
$"\t{left.FieldName}_id: Mapped[int] = mapped_column(ForeignKey(\"{left.TableName}.id\"))",
|
||||||
$"\t{left.FieldName}: Mapped[\"{left.ClassName}\"] = relationship(back_populates=\"{right.FieldName}\")"
|
$"\t{left.FieldName}: Mapped[\"{left.ClassName.Pascalize()}\"] = relationship(back_populates=\"{right.FieldName}\")"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await _context.WriteFile(left.Path, left.Rewrite());
|
await _context.WriteFile(left.Path, left.Rewrite());
|
||||||
@ -58,13 +76,13 @@ public partial class EntityLinker
|
|||||||
left.Import(from: "typing", import: "Optional");
|
left.Import(from: "typing", import: "Optional");
|
||||||
left.AppendColumns([
|
left.AppendColumns([
|
||||||
$"\t{right.FieldName}_id: Mapped[Optional[int]] = mapped_column(ForeignKey(\"{right.TableName}.id\"))",
|
$"\t{right.FieldName}_id: Mapped[Optional[int]] = mapped_column(ForeignKey(\"{right.TableName}.id\"))",
|
||||||
$"\t{right.FieldName}: Mapped[\"{right.ClassName}\"] = relationship(back_populates=\"{left.FieldName.Pluralize()}\")"
|
$"\t{right.FieldName}: Mapped[\"{right.ClassName.Pascalize()}\"] = relationship(back_populates=\"{left.FieldName.Pluralize()}\")"
|
||||||
]);
|
]);
|
||||||
left.Import(from: "typing", import: "List");
|
left.Import(from: "typing", import: "List");
|
||||||
|
|
||||||
right.AppendColumns([
|
right.AppendColumns([
|
||||||
$"\t{left.FieldName}_id: Mapped[int] = mapped_column(ForeignKey(\"{left.TableName}.id\"))",
|
$"\t{left.FieldName}_id: Mapped[int] = mapped_column(ForeignKey(\"{left.TableName}.id\"))",
|
||||||
$"\t{left.FieldName.Pluralize()}: Mapped[List[\"{left.ClassName}\"]] = relationship(back_populates=\"{right.FieldName}\")"
|
$"\t{left.FieldName.Pluralize()}: Mapped[List[\"{left.ClassName.Pascalize()}\"]] = relationship(back_populates=\"{right.FieldName}\")"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await _context.WriteFile(left.Path, left.Rewrite());
|
await _context.WriteFile(left.Path, left.Rewrite());
|
||||||
@ -73,50 +91,60 @@ public partial class EntityLinker
|
|||||||
|
|
||||||
public async Task ManyToMany()
|
public async Task ManyToMany()
|
||||||
{
|
{
|
||||||
// var left = await LoadEntity(_left);
|
var left = await LoadEntity(_left);
|
||||||
// var right = await LoadEntity(_right);
|
var right = await LoadEntity(_right);
|
||||||
//
|
|
||||||
// left.AppendImportIfNotExists(
|
var associationTable = string.Join('\n', AssociationTable);
|
||||||
// $"db.entities.{right.FieldName}",
|
associationTable = associationTable
|
||||||
// $"{right.ClassName}",
|
.Replace("%left_entity%", left.ClassName.Underscore().ToLower())
|
||||||
// $"from db.entities.{right.FieldName} import {right.ClassName}"
|
.Replace("%right_entity%", right.ClassName.Underscore().ToLower())
|
||||||
// );
|
.Replace("%left_table%", left.TableName)
|
||||||
// left.AppendImportIfNotExists(
|
.Replace("%right_table%", right.TableName);
|
||||||
// "typing",
|
var associationTablePath =
|
||||||
// "Optional",
|
$"{Features.Db.FeatureName}/entities/associations/{left.TableName.Singularize()}_{right.TableName.Singularize()}_mapping.py";
|
||||||
// "from typing import Optional"
|
|
||||||
// );
|
await _context.CreateFile(associationTablePath, associationTable);
|
||||||
// left.AppendColumn([
|
|
||||||
// $"\t{right.FieldName}_id: Mapped[Optional[int]] = mapped_column(ForeignKey(\"{right.TableName}.id\"))",
|
var associationTableImport = associationTablePath
|
||||||
// $"\t{right.FieldName}: Mapped[\"{right.ClassName}\"] = relationship(back_populates=\"{left.FieldName.Pluralize()}\")\n"
|
.Replace(".py", "")
|
||||||
// ]);
|
.Replace('/', '.')
|
||||||
//
|
.Replace('\\', '.')
|
||||||
// right.AppendImportIfNotExists(
|
.Split('.')
|
||||||
// $"db.entities.{left.FieldName}",
|
;
|
||||||
// $"{left.ClassName}",
|
|
||||||
// $"from db.entities.{left.FieldName} import {left.ClassName}"
|
var associationTableImportPath = string.Join('.', associationTableImport[..^1]);
|
||||||
// );
|
var associationTableImportName = associationTableImport[^1];
|
||||||
// left.AppendImportIfNotExists(
|
|
||||||
// "typing",
|
left.Import(from: string.Join('.', associationTableImportPath), import: associationTableImportName);
|
||||||
// "List",
|
left.Import(from: "typing", import: "List");
|
||||||
// "from typing import List"
|
right.Import(from: string.Join('.', associationTableImportPath), import: associationTableImportName);
|
||||||
// );
|
right.Import(from: "typing", import: "List");
|
||||||
// right.AppendColumn([
|
|
||||||
// $"\t{left.FieldName}_id: Mapped[int] = mapped_column(ForeignKey(\"{left.TableName}.id\"))",
|
left.AppendColumns([
|
||||||
// $"\t{left.FieldName.Pluralize()}: Mapped[List[\"{left.ClassName}\"]] = relationship(back_populates=\"{right.FieldName}\")\n"
|
$"\t{right.FieldName.Pluralize()}: Mapped[List[\"{right.ClassName.Pascalize()}\"]] = relationship(back_populates=\"{left.FieldName.Pluralize()}\", secondary={associationTableImportName})"
|
||||||
// ]);
|
]);
|
||||||
//
|
|
||||||
// await _context.WriteFile(left.Path, left.Rewrite());
|
right.AppendColumns([
|
||||||
// await _context.WriteFile(right.Path, right.Rewrite());
|
$"\t{left.FieldName.Pluralize()}: Mapped[List[\"{left.ClassName.Pascalize()}\"]] = relationship(back_populates=\"{right.FieldName.Pluralize()}\", secondary={associationTableImportName})"
|
||||||
|
]);
|
||||||
|
|
||||||
|
await _context.WriteFile(left.Path, left.Rewrite());
|
||||||
|
await _context.WriteFile(right.Path, right.Rewrite());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<EntityModel> LoadEntity(string name)
|
private async Task<EntityModel> LoadEntity(string name)
|
||||||
{
|
{
|
||||||
var path = GetEntityPath(name);
|
var path = $"{Features.Db.FeatureName}/entities";
|
||||||
|
|
||||||
|
if (name.Split(':').Select(s => s.Trim()).ToArray() is { Length: 2 } fullName)
|
||||||
|
{
|
||||||
|
path = Path.Join(path, fullName[0]);
|
||||||
|
name = fullName[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
path = Path.Join(path, $"{name.Underscore().ToLower()}.py");
|
||||||
var entity = new EntityModel(name, path, await _context.ReadFile(path));
|
var entity = new EntityModel(name, path, await _context.ReadFile(path));
|
||||||
entity.Initialize();
|
entity.Initialize();
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetEntityPath(string name) => $"{Features.Db.FeatureName}/entities/{name.Underscore().ToLower()}.py";
|
|
||||||
}
|
}
|
@ -8,11 +8,12 @@ public sealed class Db : IFeature
|
|||||||
|
|
||||||
private static readonly string[] Settings =
|
private static readonly string[] Settings =
|
||||||
[
|
[
|
||||||
"connectionstring = \"mysql+asyncmy://root:root@localhost:3306/example\"",
|
|
||||||
"",
|
|
||||||
"class DbSettings:",
|
"class DbSettings:",
|
||||||
"\tdef get_connectionstring() -> str:",
|
"\tdef get_connectionstring() -> str:",
|
||||||
"\t\treturn connectionstring"
|
"\t\t# Example",
|
||||||
|
"\t\t# connectionstring = \"mysql+asyncmy://root:root@localhost:3306/your_database\"",
|
||||||
|
"\t\t# return connectionstring",
|
||||||
|
"\t\traise Exception(\"DbSettings.get_connectionstring was not implemented.\")",
|
||||||
];
|
];
|
||||||
|
|
||||||
private static readonly string[] AsyncSession =
|
private static readonly string[] AsyncSession =
|
||||||
|
Loading…
Reference in New Issue
Block a user