Skip to content

Commit 763e11a

Browse files
committed
posts orm 객체, join 예제
1 parent 7d2f6b5 commit 763e11a

9 files changed

Lines changed: 165 additions & 76 deletions

File tree

Pipfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@ url = "https://pypi.org/simple"
44
verify_ssl = true
55

66
[dev-packages]
7-
pytest = "*"
87
pytest-cov = "*"
8+
pytest = "*"
99
pylint = "*"
1010
autopep8 = "*"
1111

1212
[packages]
1313
flask = "*"
14-
flask-script = "*"
1514
flask-sqlalchemy = "*"
1615
flask-migrate = "*"
1716
pymysql = "*"
1817
flask-restplus = "*"
1918
flask-marshmallow = "*"
2019
marshmallow-jsonapi = "*"
20+
flask-script = "*"
2121

2222
[requires]
2323
python_version = "3.7"

Pipfile.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/api/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from flask_restplus import Api
2+
3+
API = Api(title='Board API',
4+
version='1.0',
5+
description="Board REST API"
6+
# All API metadatas
7+
)

app/api/database.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,7 @@ def delete(self, resource, schema):
6060
response = (self.body, self.status_code.value)
6161
response = make_response(response)
6262
return response
63+
64+
def select(self, name, password):
65+
66+
return "test"

app/model/UserInfo.py

Lines changed: 0 additions & 18 deletions
This file was deleted.

app/model/__init__.py

Whitespace-only changes.

app/users/models.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from app.api.database import DB, CRUD
2-
from marshmallow_jsonapi import Schema, fields
2+
from marshmallow import Schema, fields
33
from flask_sqlalchemy import SQLAlchemy
44
from marshmallow import validate
55
from sqlalchemy.sql import text
66

7-
8-
class Users(DB.Model, CRUD):
7+
class Users(DB.Model):
98
__tablename__ = 'users'
109
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
1110

@@ -22,6 +21,7 @@ def __init__(self, name, email, password):
2221
self.password = password
2322

2423

24+
2525
class UsersSchema(Schema):
2626
not_blank = validate.Length(min=1, error='Field cannot be blank')
2727
id = fields.Integer(dump_only=True)
@@ -40,3 +40,23 @@ def get_top_level_links(self, data, many):
4040
class Meta:
4141
type_ = 'users'
4242
strict = True
43+
44+
45+
46+
class Post(DB.Model):
47+
__tablename__ = 'posts'
48+
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
49+
50+
id = DB.Column(DB.Integer, primary_key=True)
51+
name = DB.Column(DB.String(255), nullable=False)
52+
author_id = DB.Column(DB.Integer, DB.ForeignKey(Users.id))
53+
author = DB.relationship("Users", uselist=False)
54+
55+
def __init__(self, name: str, author_id: int):
56+
self.name = name
57+
self.author_id = author_id
58+
59+
class PostSchema(Schema):
60+
id = fields.Integer()
61+
name = fields.Str()
62+
author = fields.Nested(UsersSchema)

app/users/views.py

Lines changed: 120 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,138 @@
1+
from http import HTTPStatus
2+
from flask import jsonify
3+
from flask import make_response
14
from app.users.models import Users, UsersSchema
5+
from sqlalchemy.exc import SQLAlchemyError
26
from flask_restplus import Api, Namespace, fields, reqparse, Resource
37
from app.constants import STATUS_CODE
48
from app.constants import GET, POST, PATCH, DELETE
9+
from app.users.models import Post, PostSchema
10+
from app.api.database import DB
511

6-
API = Api(title='users',
7-
version='1.0',
8-
description="User's REST API"
9-
# All API metadatas
10-
)
12+
API = Api(title='Board API',
13+
version='1.0',
14+
description="Board REST API"
15+
# All API metadatas
16+
)
1117

1218
SCHEMA = UsersSchema()
19+
post_schema = PostSchema()
1320

1421
USER_FIELDS = API.model('Users', {
15-
'name': fields.String,
16-
'email': fields.String,
17-
'password': fields.String
22+
'name': fields.String,
23+
'email': fields.String,
24+
'password': fields.String
1825
})
26+
POST_FIELDS = API.model('Post', {
27+
'name': fields.String,
28+
'author_id': fields.Integer,
29+
})
30+
1931

2032
@API.route('/users/<int:user_id>')
2133
@API.param('user_id', 'The user identifier')
2234
class UserItem(Resource):
23-
parser = reqparse.RequestParser()
24-
parser.add_argument('name', required=True, type=str, help="user's name", location='json')
25-
parser.add_argument('email', required=True, type=str, help="user's email", location='json')
26-
parser.add_argument('password', required=True, type=str, help="password", location='json')
27-
28-
@API.doc(responses=GET)
29-
def get(self, user_id):
30-
user = Users.query.get_or_404(user_id)
31-
user = SCHEMA.dump(user).data
32-
return user
33-
34-
@API.expect(USER_FIELDS)
35-
@API.doc(responses=PATCH)
36-
def patch(self, user_id):
37-
args = self.parser.parse_args()
38-
user = Users.query.get_or_404(user_id)
39-
response = user.update(args, SCHEMA)
40-
return response
41-
42-
@API.doc(responses=DELETE)
43-
def delete(self, user_id):
44-
#import pdb; pdb.set_trace()
45-
user = Users.query.get_or_404(user_id)
46-
response = user.delete(user, SCHEMA)
47-
return response
35+
parser = reqparse.RequestParser()
36+
parser.add_argument('name', required=True, type=str, help="user's name", location='json')
37+
parser.add_argument('email', required=True, type=str, help="user's email", location='json')
38+
parser.add_argument('password', required=True, type=str, help="password", location='json')
39+
40+
@API.doc(responses=GET)
41+
def get(self, user_id):
42+
user = Users.query.get_or_404(user_id)
43+
user = SCHEMA.dump(user).data
44+
return user
45+
46+
@API.expect(USER_FIELDS)
47+
@API.doc(responses=PATCH)
48+
def patch(self, user_id):
49+
args = self.parser.parse_args()
50+
user = Users.query.get_or_404(user_id)
51+
response = user.update(args, SCHEMA)
52+
return response
53+
54+
@API.doc(responses=DELETE)
55+
def delete(self, user_id):
56+
#import pdb; pdb.set_trace()
57+
user = Users.query.get_or_404(user_id)
58+
response = user.delete(user, SCHEMA)
59+
return response
4860

4961

5062
@API.route('/users')
5163
class UsersList(Resource):
52-
parser = reqparse.RequestParser()
53-
parser.add_argument('name', required=True, type=str, help="user's name", location='json')
54-
parser.add_argument('email', required=True, type=str, help="user's email", location='json')
55-
parser.add_argument('password', required=True, type=str, help="password", location='json')
56-
57-
def get(self):
58-
users_query = Users.query.all()
59-
results = SCHEMA.dump(users_query, many=True).data
60-
return results
61-
62-
@API.expect(USER_FIELDS)
63-
def post(self):
64-
args = self.parser.parse_args()
65-
user = Users(args['name'], args['email'], args['password'])
66-
response = user.add(user, SCHEMA)
67-
return response
64+
parser = reqparse.RequestParser()
65+
parser.add_argument('name', required=True, type=str, help="user's name", location='json')
66+
parser.add_argument('email', required=True, type=str, help="user's email", location='json')
67+
parser.add_argument('password', required=True, type=str, help="password", location='json')
68+
69+
def get(self):
70+
users_query = Users.query.all()
71+
results = SCHEMA.dump(users_query, many=True).data
72+
return results
73+
74+
@API.expect(USER_FIELDS)
75+
def post(self):
76+
args = self.parser.parse_args()
77+
user = Users(args['name'], args['email'], args['password'])
78+
try:
79+
DB.session.add(user)
80+
DB.session.commit()
81+
body = jsonify({"users": SCHEMA.dump(user).data})
82+
code = HTTPStatus.OK
83+
except SQLAlchemyError as err:
84+
DB.session.rollback()
85+
message = str(err)
86+
body = jsonify({"message": message})
87+
code = HTTPStatus.INTERNAL_SERVER_ERROR
88+
return make_response(body, code.value)
89+
90+
@API.route('/posts')
91+
class Posts(Resource):
92+
parser = reqparse.RequestParser()
93+
parser.add_argument('name', required=True, type=str, help="post's name", location='json')
94+
parser.add_argument('author_id', required=True, type=int, help="post's author", location='json')
95+
96+
@API.expect(POST_FIELDS)
97+
def post(self):
98+
args_ = self.parser.parse_args()
99+
post = Post(name=args_['name'], author_id=args_['author_id'])
100+
try:
101+
DB.session.add(post)
102+
DB.session.commit()
103+
body = jsonify({"posts": post_schema.dump(post).data})
104+
code = HTTPStatus.OK
105+
except SQLAlchemyError as err:
106+
DB.session.rollback()
107+
message = str(err)
108+
body = jsonify({"message": message})
109+
code = HTTPStatus.INTERNAL_SERVER_ERROR
110+
return make_response(body, code.value)
111+
112+
@API.route('/post/<int:seqno>')
113+
class PostItem(Resource):
114+
def get(self, seqno):
115+
try:
116+
post_item = DB.session.query(Post).outerjoin(Users, Users.id==Post.author_id).filter(Post.id==seqno).first()
117+
body = jsonify({"post":post_schema.dump(post_item).data})
118+
if post_item:
119+
code = HTTPStatus.OK
120+
else:
121+
code = HTTPStatus.NOT_FOUND
122+
except SQLAlchemyError as err:
123+
message = str(err)
124+
body = jsonify({"message": message})
125+
code = HTTPStatus.INTERNAL_SERVER_ERROR
126+
return make_response(body, code.value)
127+
128+
@API.route('/userLogin')
129+
class GetUser(Resource):
130+
parser = reqparse.RequestParser()
131+
parser.add_argument('name', required=True, type=str, help="user's name", location='json')
132+
parser.add_argument('password', required=True, type=str, help="user's password", location='json')
133+
134+
@API.expect(USER_FIELDS)
135+
def post(self):
136+
args = self.parser.parse_args()
137+
user = Users.query.filter(Users.name == args['name']).first()
138+
import pdb; pdb.set_trace()

docker-compose.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,9 @@ services: # 쓰고자하는 서비스
99
ports:
1010
- "3306:3306" # 23306 포트로 접속하면 내부에서 3306포트로 전송
1111
env_file:
12-
- ./confs/database/mysql/.env # 환경 변수들을 따로 지정해줘도 되지만 파일로 떼어놓음
12+
- ./confs/database/mysql/.env # 환경 변수들을 따로 지정해줘도 되지만 파일로 떼어놓음
13+
volumes:
14+
- 'mysql-data:/var/lib/mysql'
15+
16+
volumes:
17+
mysql-data:

0 commit comments

Comments
 (0)