Commit 31c45ef7 authored by wanli's avatar wanli

æ–优化model定义时有其他非表中的字段

parent b91e4e41
......@@ -6,6 +6,7 @@ from webcreator.event import PySignal
class SignalManager(object):
actionPostArea = PySignal()
actionDeleteArea = PySignal()
actionGetListArea = PySignal()
actionGetArea = PySignal()
actionPutArea = PySignal()
......
......@@ -7,6 +7,7 @@ from .area import areaManager
def initConnect():
signalManager.actionPostArea.connect(areaManager.post)
signalManager.actionDeleteArea.connect(areaManager.delete)
signalManager.actionGetListArea.connect(areaManager.getList)
signalManager.actionGetArea.connect(areaManager.get)
signalManager.actionPutArea.connect(areaManager.put)
......
......@@ -544,3 +544,14 @@
[2021-06-11 22:11:53,811][ INFO] [ _internal.py _log 225] 127.0.0.1 - - [11/Jun/2021 22:11:53] "GET /api/v1/area HTTP/1.1" 200 -
[2021-06-11 22:11:54,441][ ERROR] [ area.py get 69] {'id': ['Unknown field.']}
[2021-06-11 22:11:54,442][ INFO] [ _internal.py _log 225] 127.0.0.1 - - [11/Jun/2021 22:11:54] "GET /api/v1/area HTTP/1.1" 200 -
[2021-06-12 11:03:45,272][ INFO] [ _internal.py _log 225] * Restarting with stat
[2021-06-12 11:03:46,709][WARNING] [ _internal.py _log 225] * Debugger is active!
[2021-06-12 11:03:46,773][ INFO] [ _internal.py _log 225] * Debugger PIN: 182-666-074
[2021-06-12 11:03:47,052][ INFO] [ _internal.py _log 225] * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
[2021-06-12 11:03:49,177][ INFO] [ _internal.py _log 225] 127.0.0.1 - - [12/Jun/2021 11:03:49] "GET /api/v1/area HTTP/1.1" 500 -
[2021-06-12 11:03:50,878][ INFO] [ _internal.py _log 225] 127.0.0.1 - - [12/Jun/2021 11:03:50] "GET /api/v1/area HTTP/1.1" 500 -
[2021-06-12 11:25:52,890][ INFO] [ _internal.py _log 225] * Detected change in 'D:\\projects\\scriptiot\\evm-store\\tools\\build_out\\webcreator\\__init__.py', reloading
[2021-06-12 11:25:53,025][ INFO] [ _internal.py _log 225] * Restarting with stat
[2021-06-15 10:51:14,114][ INFO] [ _internal.py _log 225] * Restarting with stat
[2021-06-15 10:51:15,218][WARNING] [ _internal.py _log 225] * Debugger is active!
[2021-06-15 10:51:15,280][ INFO] [ _internal.py _log 225] * Debugger PIN: 182-666-074
......@@ -23,26 +23,26 @@ def run():
生产模式启动命令函数
To use: python3 manager.py run
"""
app.logger.setLevel(app.config.get('LOG_LEVEL', logging.INFO))
service_config = {
'bind': app.config.get('BIND', '0.0.0.0:3000'),
'workers': app.config.get('WORKERS', cpu_count() * 2 + 1),
'worker_class': 'gevent',
'worker_connections': app.config.get('WORKER_CONNECTIONS', 10000),
'backlog': app.config.get('BACKLOG', 2048),
'timeout': app.config.get('TIMEOUT', 60),
'loglevel': app.config.get('LOG_LEVEL', 'info'),
'pidfile': app.config.get('PID_FILE', 'run.pid'),
}
# app.logger.setLevel(app.config.get('LOG_LEVEL', logging.INFO))
# service_config = {
# 'bind': app.config.get('BIND', '0.0.0.0:3000'),
# 'workers': app.config.get('WORKERS', cpu_count() * 2 + 1),
# 'worker_class': 'gevent',
# 'worker_connections': app.config.get('WORKER_CONNECTIONS', 10000),
# 'backlog': app.config.get('BACKLOG', 2048),
# 'timeout': app.config.get('TIMEOUT', 60),
# 'loglevel': app.config.get('LOG_LEVEL', 'info'),
# 'pidfile': app.config.get('PID_FILE', 'run.pid'),
# }
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(3000)
http_server.listen(3000, address='127.0.0.1')
# wsgi_app = WSGIContainer(app)
# application = Application([
# (r'.*', FallbackHandler, dict(fallback=wsgi_app))
# ], **service_config)
# application.listen(3000, address='127.0.0.1')
# application.listen(3000)
IOLoop.instance().start()
......
......@@ -2,7 +2,8 @@
from application.app import db, ma
from datetime import datetime
from .base import PrimaryModel
from .base import PrimaryModel
from marshmallow import Schema, fields, INCLUDE, EXCLUDE
class AreaModel(PrimaryModel):
__tablename__ = 'area'
......@@ -31,16 +32,71 @@ class AreaModel(PrimaryModel):
def __repr__(self):
return '<AreaModel %r>' % (self.areaCode)
class AreaSchema(ma.SQLAlchemySchema):
class PostAreaSchema(ma.SQLAlchemySchema):
class Meta:
# unknown = INCLUDE # 未知字段默认包含
# unknown = EXCLUDE # 未知字段默认排除
model = AreaModel
areaCode = ma.auto_field()
areaName = ma.auto_field()
level = ma.auto_field()
cityCode = ma.auto_field()
center = ma.auto_field()
postAreaSchema = PostAreaSchema()
postAreasSchema = PostAreaSchema(many=True)
class DeleteAreaSchema(ma.SQLAlchemySchema):
class Meta:
# unknown = INCLUDE # 未知字段默认包含
# unknown = EXCLUDE # 未知字段默认排除
model = AreaModel
deleteAreaSchema = DeleteAreaSchema()
class GetListAreaSchema(ma.SQLAlchemySchema):
class Meta:
# unknown = INCLUDE # 未知字段默认包含
# unknown = EXCLUDE # 未知字段默认排除
model = AreaModel
page = fields.Integer(required=False)
pageSize = fields.Integer(required=False)
areaName = ma.auto_field()
level = ma.auto_field()
parentId = ma.auto_field()
hasChildren = ma.auto_field()
field = fields.String(required=False, length=None)
getListAreaSchema = GetListAreaSchema()
class GetAreaSchema(ma.SQLAlchemySchema):
class Meta:
# unknown = INCLUDE # 未知字段默认包含
# unknown = EXCLUDE # 未知字段默认排除
model = AreaModel
areaName = ma.auto_field()
level = ma.auto_field()
parentId = ma.auto_field()
hasChildren = ma.auto_field()
field = fields.String(required=False, length=None)
getAreaSchema = GetAreaSchema()
class PutAreaSchema(ma.SQLAlchemySchema):
class Meta:
# unknown = INCLUDE # 未知字段默认包含
# unknown = EXCLUDE # 未知字段默认排除
model = AreaModel
areaName = ma.auto_field()
level = ma.auto_field()
parentId = ma.auto_field()
hasChildren = ma.auto_field()
field = fields.String(required=False, length=None)
area_schema = AreaSchema()
areas_schema = AreaSchema(many=True)
\ No newline at end of file
putAreaSchema = PutAreaSchema()
......@@ -3,7 +3,7 @@ from flask_restful import Resource
from flask_restful.reqparse import RequestParser
from flask_jwt_extended import ( jwt_required, get_jwt_identity )
from application.signal_manager import signalManager
from models.area import area_schema
from models.area import postAreaSchema,deleteAreaSchema,getListAreaSchema,getAreaSchema,putAreaSchema
from webcreator.response import ResponseCode, response_result
class AreaResource(Resource):
......@@ -23,9 +23,9 @@ class AreaResource(Resource):
try:
json_payload = request.json
print("========>", json_payload)
data = area_schema.load(json_payload)
data = getListAreaSchema.load(json_payload)
result = signalManager.actionGetArea.emit(**data)
json_dumps = area_schema.dump(result)
json_dumps = getListAreaSchema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
......@@ -36,9 +36,9 @@ class AreaResource(Resource):
def post(self):
try:
json_payload = request.json
data = area_schema.load(json_payload)
data = postAreaSchema.load(json_payload)
result = signalManager.actionPostArea.emit(**data)
json_dumps = area_schema.dump(result)
json_dumps = postAreaSchema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
......@@ -61,9 +61,9 @@ class AreaResourceList(Resource):
try:
json_payload = request.json
print("========>", json_payload)
data = area_schema.load(json_payload)
data = getAreaSchema.load(json_payload)
result = signalManager.actionGetArea.emit(**data)
json_dumps = area_schema.dump(result)
json_dumps = getAreaSchema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
......@@ -74,9 +74,9 @@ class AreaResourceList(Resource):
def put(self):
try:
json_payload = request.json
data = area_schema.load(json_payload)
data = putAreaSchema.load(json_payload)
result = signalManager.actionPutArea.emit(**data)
json_dumps = area_schema.dump(result)
json_dumps = putAreaSchema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
......@@ -87,9 +87,9 @@ class AreaResourceList(Resource):
def delete(self):
try:
json_payload = request.json
data = area_schema.load(json_payload)
data = deleteAreaSchema.load(json_payload)
result = signalManager.actionDeleteArea.emit(**data)
json_dumps = area_schema.dump(result)
json_dumps = deleteAreaSchema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
......
......@@ -28,12 +28,12 @@ def pushmessage(func):
try:
if isinstance(msg, WebsocketResponse) or isinstance(msg, dict):
self.write_message(json.dumps(msg), binary)
elif isinstance(msg, str) or isinstance(msg, unicode):
elif isinstance(msg, str) or isinstance(msg, str):
self.write_message(msg, binary)
else:
self.write_message(repr(msg), binary)
except WebSocketClosedError as e:
logger.error(e)
self.on_close()
return send
......
......@@ -14,7 +14,7 @@
"database": "app"
},
"sqlite": {
"file": "xxx.db"
"file": "test.db"
}
},
"apis": [
......@@ -54,7 +54,7 @@
{
"name": "cityCode",
"dataType": "Integer",
"default": ""
"default": 0
},
{
"name": "center",
......@@ -87,35 +87,35 @@
"params": [
{
"name": "areaCode",
"dataType": "str",
"dataType": "String",
"location": "json",
"default": "",
"required": false
},
{
"name": "areaName",
"dataType": "str",
"dataType": "String",
"location": "json",
"default": "",
"required": false
},
{
"name": "level",
"dataType": "int",
"dataType": "Integer",
"location": "",
"default": "",
"default": 1,
"required": false
},
{
"name": "cityCode",
"detaType": "str",
"detaType": "String",
"location": "",
"default": "",
"required": false
},
{
"name": "center",
"dataType": "str",
"dataType": "String",
"location": "",
"default": "",
"required": false
......@@ -128,56 +128,98 @@
"endpoint": "",
"params": []
},
"get": {
"auth": true,
"path": "/area/<string:uuid>",
"getList": {
"auth": false,
"path": "/area",
"endpoint": "",
"params": [
{
"name": "pageNum",
"dataType": "int",
"name": "page",
"dataType": "Integer",
"location": "args",
"default": 1,
"required": false
},
{
"name": "pageSize",
"dataType": "int",
"dataType": "Integer",
"location": "args",
"default": 10,
"required": false
},
{
"name": "areaName",
"dataType": "str",
"dataType": "String",
"location": "args",
"default": null,
"required": false
},
{
"name": "level",
"dataType": "int",
"dataType": "Integer",
"location": "args",
"default": null,
"default": 1,
"required": false
},
{
"name": "parentId",
"dataType": "int",
"dataType": "String",
"location": "args",
"default": null,
"default": "",
"required": false
},
{
"name": "hasChildren",
"dataType": "bool",
"dataType": "Boolean",
"location": "args",
"default": false,
"required": false
},
{
"name": "field",
"dataType": "String",
"location": "args",
"default": "",
"required": false
}
]
},
"get": {
"auth": true,
"path": "/area/<string:uuid>",
"endpoint": "",
"params": [
{
"name": "areaName",
"dataType": "String",
"location": "args",
"default": "",
"required": false
},
{
"name": "level",
"dataType": "Integer",
"location": "args",
"default": null,
"required": false
},
{
"name": "parentId",
"dataType": "String",
"location": "args",
"default": "",
"required": false
},
{
"name": "hasChildren",
"dataType": "Boolean",
"location": "args",
"default": false,
"required": false
},
{
"name": "field",
"dataType": "str",
"dataType": "String",
"location": "args",
"default": null,
"required": false
......@@ -191,35 +233,35 @@
"params": [
{
"name": "areaName",
"dataType": "str",
"dataType": "String",
"location": "args",
"default": null,
"default": "",
"required": false
},
{
"name": "level",
"dataType": "int",
"dataType": "Integer",
"location": "args",
"default": null,
"default": 0,
"required": false
},
{
"name": "parentId",
"dataType": "int",
"dataType": "String",
"location": "args",
"default": null,
"required": false
},
{
"name": "hasChildren",
"dataType": "bool",
"dataType": "Boolean",
"location": "args",
"default": null,
"default": false,
"required": false
},
{
"name": "field",
"dataType": "str",
"dataType": "String",
"location": "args",
"default": null,
"required": false
......
......@@ -44,8 +44,16 @@ def handleSignal(config):
def handleModel(config):
# 将所有有默认值的字段分为一组,没有默认值的字段分为另一组
# 生成模板代码时,无默认值的字段在前,有默认值的字段字在后
# 收集表字段信息
fields = []
extend = False
for m in config.get("model").get("fields"):
fields.append(m.get("name"))
extend = True
print(m)
target_file = os.sep.join(["models", "{}.py".format(config.get("name"))])
handleRender(config, 'model.tpl', target_file)
handleRender(config, 'model.tpl', target_file, fields=fields, extend=extend)
def handleView(config):
target_file = os.sep.join(["views", "{}.py".format(config.get("name"))])
......@@ -56,11 +64,11 @@ def handleController(config):
target_file = os.sep.join(["controllers", "{}.py".format(config.get("name"))])
handleRender(config, 'controller.tpl', target_file)
def handleRender(result, tpl, target_file):
def handleRender(result, tpl, target_file, **kwargs):
global output_dir
# print("=========>", result.get("name"), "{}.py".format(result.get("name")))
jinja_tpl = jinja_env.get_template(tpl)
content = jinja_tpl.render({ "config": result })
content = jinja_tpl.render({ "config": result, **kwargs })
# print("############", output_dir)
target_file = os.sep.join([output_dir, target_file])
if not os.path.exists(os.path.dirname(target_file)):
......
# 模板文件定义标准
## model
### 字段类型
字段类型只能定义如下类型:
- Integer
- String
- Boolean
## view
## controller
\ No newline at end of file
......@@ -3,6 +3,9 @@
from application.app import db, ma
from datetime import datetime
from .base import PrimaryModel
{%- if extend %} {# 判断是否有扩展字段,也就是model对象不包含的字段,因为查询里面还有pagepageSize等这两种字段 #}
from marshmallow import Schema, fields, INCLUDE, EXCLUDE
{%- endif %}
class {{ config['model']['className'] }}(PrimaryModel):
__tablename__ = '{{ config['model']['tableName'] }}'
......@@ -28,16 +31,45 @@ class {{ config['model']['className'] }}(PrimaryModel):
def __repr__(self):
return '<{{ config['model']['className'] }} %r>' % (self.{{ config['model']['fields'][0]["name"] }})
class {{ config['name'] | letterUpper }}Schema(ma.SQLAlchemySchema):
{% for key, value in config["view"].items() %}
class {{ key |letterUpper }}{{ config['name'] | letterUpper }}Schema(ma.SQLAlchemySchema):
class Meta:
# unknown = INCLUDE # 未知字段默认包含
# unknown = EXCLUDE # 未知字段默认排除
model = {{ config['model']['className'] }}
{%- if config['model']['foreignKey'] %}
include_fk = {{ config['model']['foreignKey'] }}
{% endif %}
{#
这里需要判断下,如果是数据库表的字段,则使用auto_field(),否则应该使用json配置中的字段信息
{%- for value in config['model']['fields'] %}
{{ value.get("name") }} = ma.auto_field()
class BandMembersSchema(Schema):
# missing用来指定反序列化时默认缺省值,default用来指定序列化时默认缺省值
# 在通常的web api中,dump_onlyload_only参数就类似于“read-only”和“write-only”字段
id = fields.UUID(missing=uuid.uuid1)
name = fields.String(required=True, validate=validate.Length(min=1)) # 更多校验类型,移步:https://marshmallow.readthedocs.io/en/stable/api_reference.html#api-validators
email = fields.Email(data_key="emailAddress") # 解决序列化与反序列化字段不一致问题
birthdate = fields.DateTime(default=dt.datetime(2017, 9, 29))
city = fields.String(
required=True,
error_messages={"required": {"message": "City required", "code": 400}},
)
age = fields.Int(validate=validate.Range(min=18, max=40))
permission = fields.Str(validate=validate.OneOf(["read", "write", "admin"]))
password = fields.Str(load_only=True) # password is "write-only"
created_at = fields.DateTime(dump_only=True) # created_at is "read-only"
#}
{%- for p in value['params'] %}
{%- if p.get("name") in fields %}
{{ p.get("name") }} = ma.auto_field()
{%- else %}
{{ p.get("name") }} = fields.{{ p.get("dataType") }}(required={{ p.get("required") }}{%- if p.get("dataType") == "String" %}, length={{ p.get("length") }}{%- endif %})
{%- endif %}
{%- endfor %}
{{ config['name'] }}_schema = {{ config['name'] | letterUpper }}Schema()
{{ config['name'] }}s_schema = {{ config['name'] | letterUpper }}Schema(many=True)
\ No newline at end of file
{{ key }}{{ config['name'] | letterUpper }}Schema = {{ key | letterUpper }}{{ config['name'] | letterUpper }}Schema()
{%- if key == "post" %}
{{ key }}{{ config['name'] | letterUpper }}sSchema = {{ key | letterUpper }}{{ config['name'] | letterUpper }}Schema(many=True)
{%- endif %}
{% endfor %}
\ No newline at end of file
......@@ -3,7 +3,10 @@ from flask_restful import Resource
from flask_restful.reqparse import RequestParser
from flask_jwt_extended import ( jwt_required, get_jwt_identity )
from application.signal_manager import signalManager
from models.{{ config['name'] }} import {{ config['name'] }}_schema
{%- set pipe = joiner(",") %}
from models.{{ config['name'] }} import {% for k, v in config["view"].items() -%}
{{ pipe() }}{{ k }}{{ config['name'] | letterUpper }}Schema
{%- endfor %}
from webcreator.response import ResponseCode, response_result
class {{ config['controller']['className'] | letterUpper }}(Resource):
......@@ -12,7 +15,7 @@ class {{ config['controller']['className'] | letterUpper }}(Resource):
# 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
# self.parser = RequestParser()
{% if config["view"]["post"] %}
{% if config["view"]["getList"] %}
@jwt_required
{%- endif %}
def get(self):
......@@ -24,9 +27,9 @@ class {{ config['controller']['className'] | letterUpper }}(Resource):
try:
json_payload = request.json
print("========>", json_payload)
data = {{ config['name'] }}_schema.load(json_payload)
data = getList{{ config['name'] | letterUpper }}Schema.load(json_payload)
result = signalManager.actionGet{{ config["name"] | letterUpper }}.emit(**data)
json_dumps = {{ config['name'] }}_schema.dump(result)
json_dumps = getList{{ config['name'] | letterUpper }}Schema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
......@@ -38,9 +41,9 @@ class {{ config['controller']['className'] | letterUpper }}(Resource):
def post(self):
try:
json_payload = request.json
data = {{ config['name'] }}_schema.load(json_payload)
data = post{{ config['name'] | letterUpper }}Schema.load(json_payload)
result = signalManager.actionPost{{ config["name"] | letterUpper }}.emit(**data)
json_dumps = {{ config['name'] }}_schema.dump(result)
json_dumps = post{{ config['name'] |letterUpper }}Schema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
......@@ -52,7 +55,7 @@ class {{ config['controller']['className'] | letterUpper }}List(Resource):
# 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
# self.parser = RequestParser()
{% if config["view"]["post"] %}
{% if config["view"]["get"] %}
@jwt_required
{%- endif %}
def get(self):
......@@ -64,37 +67,37 @@ class {{ config['controller']['className'] | letterUpper }}List(Resource):
try:
json_payload = request.json
print("========>", json_payload)
data = {{ config['name'] }}_schema.load(json_payload)
data = get{{ config['name'] | letterUpper }}Schema.load(json_payload)
result = signalManager.actionGet{{ config["name"] | letterUpper }}.emit(**data)
json_dumps = {{ config['name'] }}_schema.dump(result)
json_dumps = get{{ config['name'] | letterUpper }}Schema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
return response_result(ResponseCode.DB_ERROR)
{% if config["view"]["post"] %}
{% if config["view"]["put"] %}
@jwt_required
{%- endif %}
def put(self):
try:
json_payload = request.json
data = {{ config['name'] }}_schema.load(json_payload)
data = put{{ config['name'] | letterUpper }}Schema.load(json_payload)
result = signalManager.actionPut{{ config["name"] | letterUpper }}.emit(**data)
json_dumps = {{ config['name'] }}_schema.dump(result)
json_dumps = put{{ config['name'] | letterUpper }}Schema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
return response_result(ResponseCode.DB_ERROR)
{% if config["view"]["post"] %}
{% if config["view"]["delete"] %}
@jwt_required
{%- endif %}
def delete(self):
try:
json_payload = request.json
data = {{ config['name'] }}_schema.load(json_payload)
data = delete{{ config['name'] | letterUpper }}Schema.load(json_payload)
result = signalManager.actionDelete{{ config["name"] | letterUpper }}.emit(**data)
json_dumps = {{ config['name'] }}_schema.dump(result)
json_dumps = delete{{ config['name'] | letterUpper }}Schema.dump(result)
return jsonify(json_dumps), 200
except Exception as e:
current_app.logger.error(e)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment