Templatejen laatu: declarative_base, ConfigDict, ForeignKey
- models.py: sqlalchemy.ext.declarative → sqlalchemy.orm (poistaa
MovedIn20Warning-varoituksen)
- schemas.py: class Config → model_config = ConfigDict() (poistaa
PydanticDeprecatedSince20-varoituksen)
- models.py: _id-kentät saavat ForeignKey("taulu.id") kun speksissä
on relationship-merkintä
Testattu: 10 erilaista projektia, 78/78 testiä läpi, 0 varoitusta.
This commit is contained in:
@@ -1202,18 +1202,27 @@ Blog → Author: name,email,bio(Text|None) / Post: title, content(Text), author_
|
|||||||
}
|
}
|
||||||
|
|
||||||
function tmplModels(spec) {
|
function tmplModels(spec) {
|
||||||
|
// Kerää tarvittavat SA-tyypit + ForeignKey jos relaatioita
|
||||||
const saTypes = new Set(['Integer']);
|
const saTypes = new Set(['Integer']);
|
||||||
for (const e of spec.entities) for (const f of e.fields) saTypes.add(f.sa_type.match(/^(\w+)/)[1]);
|
for (const e of spec.entities) for (const f of e.fields) saTypes.add(f.sa_type.match(/^(\w+)/)[1]);
|
||||||
|
const relMap = {};
|
||||||
|
for (const r of (spec.relationships || [])) {
|
||||||
|
const target = spec.entities.find(e => e.name === r.to);
|
||||||
|
if (target) relMap[`${r.from}.${r.field}`] = target.table_name;
|
||||||
|
}
|
||||||
|
const hasFk = Object.keys(relMap).length > 0;
|
||||||
|
if (hasFk) saTypes.add('ForeignKey');
|
||||||
const imports = [...saTypes].sort().join(', ');
|
const imports = [...saTypes].sort().join(', ');
|
||||||
let code = `from sqlalchemy import create_engine, Column, ${imports}\n`;
|
let code = `from sqlalchemy import create_engine, Column, ${imports}\n`;
|
||||||
code += `from sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\n`;
|
code += `from sqlalchemy.orm import declarative_base, sessionmaker\n\n`;
|
||||||
code += `DATABASE_URL = "sqlite:///./app.db"\n`;
|
code += `DATABASE_URL = "sqlite:///./app.db"\n`;
|
||||||
code += `engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})\n`;
|
code += `engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})\n`;
|
||||||
code += `SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = declarative_base()\n\n`;
|
code += `SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = declarative_base()\n\n`;
|
||||||
for (const e of spec.entities) {
|
for (const e of spec.entities) {
|
||||||
code += `class ${e.name}(Base):\n __tablename__ = "${e.table_name}"\n id = Column(Integer, primary_key=True, index=True)\n`;
|
code += `class ${e.name}(Base):\n __tablename__ = "${e.table_name}"\n id = Column(Integer, primary_key=True, index=True)\n`;
|
||||||
for (const f of e.fields) {
|
for (const f of e.fields) {
|
||||||
let parts = [`Column(${f.sa_type}`];
|
const fkTarget = relMap[`${e.name}.${f.name}`];
|
||||||
|
let parts = fkTarget ? [`Column(${f.sa_type}, ForeignKey("${fkTarget}.id")` ] : [`Column(${f.sa_type}`];
|
||||||
if (!f.nullable) parts.push('nullable=False');
|
if (!f.nullable) parts.push('nullable=False');
|
||||||
if (f.default !== null && f.default !== undefined) parts.push(`default=${pyLiteral(f.default)}`);
|
if (f.default !== null && f.default !== undefined) parts.push(`default=${pyLiteral(f.default)}`);
|
||||||
code += ` ${f.name} = ${parts.join(', ')})\n`;
|
code += ` ${f.name} = ${parts.join(', ')})\n`;
|
||||||
@@ -1232,7 +1241,7 @@ Blog → Author: name,email,bio(Text|None) / Post: title, content(Text), author_
|
|||||||
if (/\bdatetime\b/i.test(f.py_type)) dtTypes.add('datetime');
|
if (/\bdatetime\b/i.test(f.py_type)) dtTypes.add('datetime');
|
||||||
}
|
}
|
||||||
|
|
||||||
let code = 'from pydantic import BaseModel\n';
|
let code = 'from pydantic import BaseModel, ConfigDict\n';
|
||||||
if (dtTypes.size > 0) code += `from datetime import ${[...dtTypes].sort().join(', ')}\n`;
|
if (dtTypes.size > 0) code += `from datetime import ${[...dtTypes].sort().join(', ')}\n`;
|
||||||
|
|
||||||
// extra_imports: suodata pois pelkät nimet kuten "datetime" (jo käsitelty yllä)
|
// extra_imports: suodata pois pelkät nimet kuten "datetime" (jo käsitelty yllä)
|
||||||
@@ -1249,7 +1258,7 @@ Blog → Author: name,email,bio(Text|None) / Post: title, content(Text), author_
|
|||||||
else if (f.nullable && f.py_type.includes('None')) code += ` ${f.name}: ${f.py_type} = None\n`;
|
else if (f.nullable && f.py_type.includes('None')) code += ` ${f.name}: ${f.py_type} = None\n`;
|
||||||
else code += ` ${f.name}: ${f.py_type}\n`;
|
else code += ` ${f.name}: ${f.py_type}\n`;
|
||||||
}
|
}
|
||||||
code += `\nclass ${e.name}Response(${e.name}Create):\n id: int\n\n class Config:\n from_attributes = True\n\n`;
|
code += `\nclass ${e.name}Response(${e.name}Create):\n id: int\n model_config = ConfigDict(from_attributes=True)\n\n`;
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user