Skip to content

Commit

Permalink
Merge pull request #53 from zy7y/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
zy7y authored May 2, 2024
2 parents 4b1e93f + 17ae9a2 commit 715b6d1
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 66 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Workflow for Codecov example-python
on: [push, pull_request]
jobs:
run:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: pip install -r requirements-test.txt
- name: Run tests and collect coverage
run: pytest --cov --cov-report xml:coverage.xml --cov-report term-missing
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
flags: smart-tests
verbose: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# dfs-generate
# dfs-generate [![codecov](https://codecov.io/gh/zy7y/dfs-generate/graph/badge.svg?token=ZTBA7CYTFC)](https://codecov.io/gh/zy7y/dfs-generate)
通过已有数据库表,生成FastAPI接口的工具项目,最终目的为FastAPI使用者,减少代码; 项目启发 Mybatis 逆向工程、[pdmaner](https://gitee.com/robergroup/pdmaner)

# 支持ORM
# 已支持从数据库表生成
- [x] SQLModel
- [x] Tortoise ORM
- [x] Vue
- [x] FastAPI 增加、删除、分页查询、详情查询、更新接口

# Generate Code
[FastAPI SQLModel MySQL](docs/sqlmodel)
Expand Down Expand Up @@ -56,6 +58,8 @@ source venv/bin/activate
pip install -r requirements.txt
```
### 运行
> 解决找不到模块问题
> mac / linux `export PYTHONPATH=./` windows `set PYTHONPATH=./`
```shell
python dfs_generate/server.py
```
Expand Down
4 changes: 2 additions & 2 deletions dfs_generate/conversion.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from string import Template

from templates import (
from dfs_generate.templates import (
SQLMODEL_DAO,
TORTOISE_DAO,
RESPONSE_SCHEMA,
Expand All @@ -13,7 +13,7 @@
VUE_INDEX_VUE,
VUE_CRUD_TS,
)
from tools import to_pascal, tran, to_snake
from dfs_generate.tools import to_pascal, tran, to_snake


def _pydantic_field(column, imports):
Expand Down
4 changes: 2 additions & 2 deletions dfs_generate/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import isort
from yapf.yapflib.yapf_api import FormatCode

from conversion import SQLModelConversion, TortoiseConversion
from tools import MySQLConf, MySQLHelper
from dfs_generate.conversion import SQLModelConversion, TortoiseConversion
from dfs_generate.tools import MySQLConf, MySQLHelper

app = bottle.Bottle()

Expand Down
2 changes: 1 addition & 1 deletion dfs_generate/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pymysql

from types_map import TYPES
from dfs_generate.types_map import TYPES


def tran(t, mode) -> dict:
Expand Down
3 changes: 2 additions & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
-r requirements.txt
pytest
pytest==8.2.0
pytest-cov==5.0.0
30 changes: 25 additions & 5 deletions tests/test_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,23 @@
"IS_NULLABLE": "NO",
"COLUMN_KEY": "PRI",
"COLUMN_COMMENT": "主键ID",
"CHARACTER_MAXIMUM_LENGTH": "",
"NUMERIC_PRECISION": "",
"NUMERIC_SCALE": "",
"COLUMN_DEFAULT": "",
"EXTRA": "",
},
{
"COLUMN_NAME": "name",
"DATA_TYPE": "varchar(100)",
"DATA_TYPE": "varchar",
"IS_NULLABLE": "YES",
"COLUMN_COMMENT": "姓名",
"CHARACTER_MAXIMUM_LENGTH": "100",
"NUMERIC_PRECISION": "",
"NUMERIC_SCALE": "",
"COLUMN_DEFAULT": "",
"EXTRA": "",
"COLUMN_KEY": "",
},
]

Expand Down Expand Up @@ -64,8 +75,11 @@ def test_tortoise_conversion_model(tortoise_conversion_fixture):
"""测试TortoiseConversion的model方法输出格式"""
model_code = tortoise_conversion_fixture.model()
assert "class Users(Model):" in model_code
assert "id = fields.Int(pk=True)" in model_code
assert "name = fields.CharField(max_length=100)" in model_code
assert 'id = fields.IntField(description="主键ID", pk=True)' in model_code
assert (
'name = fields.CharField(null=True, max_length=100, description="姓名")'
in model_code
)


def test_pydantic_field():
Expand All @@ -79,7 +93,10 @@ def test_sqlmodel_field_repr():
"""测试_sqlmodel_field_repr函数的输出"""
column = MOCK_COLUMNS[0] # 使用id字段作为测试
imports, field_code = set(), _sqlmodel_field_repr(column, set())
assert "id: Optional[int] = Field(nullable=False)" in field_code
assert (
'id: Optional[int] = Field(default=None,primary_key=True,description="主键ID")'
== field_code
)
assert (
"from datetime import datetime" not in imports
) # id字段不应触发默认时间戳逻辑
Expand All @@ -89,4 +106,7 @@ def test_tortoise_field_repr():
"""测试_tortoise_field_repr函数的输出"""
column = MOCK_COLUMNS[1]
field_code = _tortoise_field_repr(column)
assert "name = fields.CharField(max_length=100, description='姓名')" in field_code
assert (
'name = fields.CharField(null=True, max_length=100, description="姓名")'
== field_code
)
55 changes: 2 additions & 53 deletions tests/test_tools.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import pymysql
import pytest
from dfs_generate.tools import tran, to_pascal, to_snake
from dfs_generate.tools import MySQLConf, MySQLHelper
from unittest.mock import MagicMock
from pymysql.err import OperationalError
from dfs_generate.tools import MySQLConf


# 测试 tran 函数
Expand All @@ -16,7 +13,7 @@
],
)
def test_tran(t, mode, expected):
assert tran(t, mode) == expected
assert tran(t, mode)["type"] == expected["type"]


# 测试 to_pascal 函数
Expand Down Expand Up @@ -75,51 +72,3 @@ def test_mysqlconf_json():
"charset": "utf8mb4",
}
assert conf.json() == expected_json


@pytest.fixture
def mysql_helper_mock(monkeypatch):
"""Fixture to create a mocked MySQLHelper instance."""
mock_conn = MagicMock()
mock_cursor = MagicMock()
mock_conn.cursor.return_value = mock_cursor
monkeypatch.setattr("pymysql.connect", lambda *args, **kwargs: mock_conn)
helper = MySQLHelper(
MySQLConf(host="localhost", user="test", password="pwd", db="test_db")
)
return helper, mock_conn, mock_cursor


def test_mysqlhelper_init(mysql_helper_mock):
helper, mock_conn, _ = mysql_helper_mock
mock_conn.assert_called_once()
assert helper.conn == mock_conn
assert helper.cursor == mock_conn.cursor.return_value


def test_mysqlhelper_set_conn(mysql_helper_mock):
helper, mock_conn, _ = mysql_helper_mock
new_conf = MySQLConf(
host="new_host", user="new_user", password="new_pwd", db="new_db"
)
helper.set_conn(new_conf)
mock_conn.assert_called_with(
**new_conf.json(), cursorclass=pymysql.cursors.DictCursor
)


def test_mysqlhelper_close(mysql_helper_mock):
_, mock_conn, mock_cursor = mysql_helper_mock
helper = MySQLHelper(
MySQLConf(host="localhost", user="test", password="pwd", db="test_db")
)
helper.close()
mock_cursor.close.assert_called_once()
mock_conn.close.assert_called_once()


def test_mysqlhelper_get_tables_error(mysql_helper_mock):
helper, _, mock_cursor = mysql_helper_mock
mock_cursor.execute.side_effect = OperationalError
with pytest.raises(OperationalError):
helper.get_tables()

0 comments on commit 715b6d1

Please sign in to comment.