{
    "componentChunkName": "component---src-templates-post-tsx",
    "path": "/flask/",
    "result": {"data":{"logo":null,"markdownRemark":{"html":"<h2>Flask</h2>\n<ul>\n<li>Flask는 ‘micro’웹 프레임워크입니다.</li>\n<li>즉 Django와 달리 최소한의 구성 요소와 요구 사항을 제공하기 때문에 시작하기 쉽고 필요에 따라 유연하게 사용할 수 있습니다.</li>\n<li>하지만 완전한 기능을 갖춘 앱을 만들기에 제약이 있다는 뜻은 아니고 오히려 쉽게 확장할 수 있도록 설계되어 있습니다.</li>\n</ul>\n<h3>install</h3>\n<p><code class=\"language-text\">pip install flask</code></p>\n<h3>Hello Flask</h3>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> flask <span class=\"token keyword\">import</span> Flask\napp <span class=\"token operator\">=</span> Flask<span class=\"token punctuation\">(</span>__name__<span class=\"token punctuation\">)</span>  <span class=\"token comment\"># Flask 객체 생성</span>\n \n<span class=\"token decorator annotation punctuation\">@app<span class=\"token punctuation\">.</span>route</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">index</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token string\">'&lt;h1>Hello World!&lt;/h1>'</span>\n \n<span class=\"token keyword\">if</span> __name__ <span class=\"token operator\">==</span> <span class=\"token string\">\"__main__\"</span><span class=\"token punctuation\">:</span>\n    app<span class=\"token punctuation\">.</span>run<span class=\"token punctuation\">(</span>debug<span class=\"token operator\">=</span><span class=\"token boolean\">True</span><span class=\"token punctuation\">,</span> port<span class=\"token operator\">=</span><span class=\"token number\">5000</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Flask를 처음 시작할 때 생성하는 hello world 출력 코드입니다.</p>\n<p>정말 간단한 코드지만 Flask의 기본적인 구조를 잘 보여주고 있습니다.</p>\n<p>app은 Flask객체입니다. 원하는 기능을 추가하고 싶을 때 이 app에 기능을 추가해주면되고, 특정 url에 기능을 추가하고 싶을 경우에도 app을 기준으로 url을 추가해준 뒤 기능을 구현해주면 됩니다.</p>\n<p>아무튼 이렇게 실행을 하면 <code class=\"language-text\">app.run()</code>을 통해 <code class=\"language-text\">http://127.0.0.1:5000/</code> 주소로 app이 배포가 시작됩니다.</p>\n<p>5000번 port는 flask에서 실행한 서버의 포트이며, <code class=\"language-text\">debug=True</code> 개발용으로 실행한다는 뜻으로 프로젝트에서 변경된 코드가 생길 시 자동으로 변경된 코드를 적용해서 서버를 다시 시작해주는 기능을 갖고 있습니다.</p>\n<br>\n<h3>Route</h3>\n<p>Flask를 사용시 어쩌면 가장 중요하다고 할 수 있는 route기능입니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> flask <span class=\"token keyword\">import</span> Flask\n\napp <span class=\"token operator\">=</span> Flask<span class=\"token punctuation\">(</span>__name__<span class=\"token punctuation\">)</span>\n\n<span class=\"token decorator annotation punctuation\">@app<span class=\"token punctuation\">.</span>route</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span><span class=\"token punctuation\">)</span>\n<span class=\"token decorator annotation punctuation\">@app<span class=\"token punctuation\">.</span>route</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/home'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">home</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token string\">'Hello, World!'</span>\n\n<span class=\"token decorator annotation punctuation\">@app<span class=\"token punctuation\">.</span>route</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/user'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">user</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token string\">'Hello, User!'</span>\n\n<span class=\"token keyword\">if</span> __name__ <span class=\"token operator\">==</span> <span class=\"token string\">'__main__'</span><span class=\"token punctuation\">:</span>\n    app<span class=\"token punctuation\">.</span>run<span class=\"token punctuation\">(</span>debug<span class=\"token operator\">=</span><span class=\"token boolean\">True</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>route는 말 그대로 경로를 지정해주는 기능입니다.</p>\n<p>이게 무슨말이냐. 보통 웹에 배포를 시작할 경우 다양한 기능들(로그인, 검색, 메뉴 등등)을 제공해야 하는데 <code class=\"language-text\">http://127.0.0.1:5000/</code> 이라는 주소 하나만으로는 모든 기능을 처리할 수 없습니다.\n그렇다고 저 주소안에 여러기능들을 다 쑤셔넣을 수도 없으니까요.</p>\n<p>이 <code class=\"language-text\">app.route</code> 데코레이터를 이용해 url의 suffix를 추가해줄 수 있습니다.</p>\n<p>위에 코드를 예시로 들어보면 home 함수에는 <code class=\"language-text\">/home</code>, <code class=\"language-text\">/</code>이라는 문자가 route 데코레이터를 통해 추가된 것을 확인할 수 있습니다.</p>\n<p>이 말은 <code class=\"language-text\">http://127.0.0.1:5000/</code> 또는 <code class=\"language-text\">http://127.0.0.1:5000/home</code> 에 접속할 경우 home 함수를 실행하라는 뜻입니다.</p>\n<p>마찬가지로 <code class=\"language-text\">http://127.0.0.1:5000/user</code> 에 접속 시 user함수가 실행되는 것을 알 수 있습니다.</p>\n<br>\n<h3>Blueprint</h3>\n<p>굉장히 중요한 기능인 이 route는 기능이 필요할 때마다 계속 추가되어야 하기 때문에, 함수가 많을 경우 번거로워질 수 있습니다.</p>\n<p>예를 들면 동일하게 <code class=\"language-text\">/menu</code> 로 시작하는 url이 있는 경우 2~3개면 상관없겠지만 실제 프로젝트에선 10개가 넘어갈 수도 있는데 전부 하나씩 menu를 달아주는 것은 비효율적입니다.</p>\n<p>이런 상황에서 blueprint를 이용하면 route함수들을 보다 구조적으로 관리할 수 있게 됩니다.</p>\n<h3>Blueprint 객체</h3>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token comment\"># app.py</span>\n<span class=\"token keyword\">from</span> flask <span class=\"token keyword\">import</span> Flask\n\napp <span class=\"token operator\">=</span> Flask<span class=\"token punctuation\">(</span>__name__<span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">from</span> <span class=\"token punctuation\">.</span>views <span class=\"token keyword\">import</span> main_views\t\napp<span class=\"token punctuation\">.</span>register_blueprint<span class=\"token punctuation\">(</span>main_views<span class=\"token punctuation\">.</span>bp<span class=\"token punctuation\">)</span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token comment\"># views\\main_views.py</span>\n<span class=\"token keyword\">from</span> flask <span class=\"token keyword\">import</span> Blueprint\n\nbp <span class=\"token operator\">=</span> Blueprint<span class=\"token punctuation\">(</span><span class=\"token string\">'main_views'</span><span class=\"token punctuation\">,</span> __name__<span class=\"token punctuation\">,</span> url_prefix<span class=\"token operator\">=</span><span class=\"token string\">'/view'</span><span class=\"token punctuation\">)</span>\n\n\n<span class=\"token decorator annotation punctuation\">@bp<span class=\"token punctuation\">.</span>route</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/hello'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">main_view</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token string\">'main view'</span></code></pre></div>\n<ol>\n<li>blueprint 객체 생성</li>\n<li>Flask 객체 app에서 blueprint객체를 register해준다.</li>\n<li>controller route에서 blueprint 객체를 써준다.</li>\n</ol>\n<p>최종적으로 hello_pybo함수의 url은 <code class=\"language-text\">127.0.0.1:5000/view/hello</code>가 됩니다.</p>\n<p>이런 식으로 blueprint를 사용하여 url을 구조적으로 관리해줄 수 있습니다.</p>\n<h3>app teardown appcontext</h3>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token decorator annotation punctuation\">@app<span class=\"token punctuation\">.</span>teardown_appcontext</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">shutdown_session</span><span class=\"token punctuation\">(</span>exception<span class=\"token operator\">=</span><span class=\"token boolean\">None</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    db_session<span class=\"token punctuation\">.</span>remove<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p><code class=\"language-text\">app.teardown_appcontext</code>데코레이터는 클라이언트의 요청이 종료됐을 경우에 자동으로 실행되도록 하는 함수입니다.</p>\n<p>위 함수를 읽기만해도 알 수 있듯이 클라이언트의 요청이 종료될 경우 해당함수가 실행돼 db가 종료되도록 한다는 뜻입니다.</p>\n<p>매우 간단하지만 중요한 개념이기 때문에 언급하고 넘어가겠습니다.</p>\n<h2>Database</h2>\n<p>이번엔 flask에 database를 연동하는 방법을 알아보겠습니다.</p>\n<p>흔히들 python에 database에 연동할 때 각 sql을 지원하는 라이브러리의 connect()함수를 사용하여 연동했을겁니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token comment\"># ex) mysql 연결</span>\n<span class=\"token keyword\">import</span> pymysql \n\nconn <span class=\"token operator\">=</span> pymysql<span class=\"token punctuation\">.</span>connect<span class=\"token punctuation\">(</span>\n    user<span class=\"token operator\">=</span><span class=\"token string\">'root'</span><span class=\"token punctuation\">,</span> \n    passwd<span class=\"token operator\">=</span><span class=\"token string\">'{설정한 비밀번호}'</span><span class=\"token punctuation\">,</span> \n    host<span class=\"token operator\">=</span><span class=\"token string\">'127.0.0.1'</span><span class=\"token punctuation\">,</span> \n    db<span class=\"token operator\">=</span><span class=\"token string\">'juso-db'</span><span class=\"token punctuation\">,</span> \n    charset<span class=\"token operator\">=</span><span class=\"token string\">'utf8'</span>\n<span class=\"token punctuation\">)</span></code></pre></div>\n<p>이런 식으로 간단하게 연동한 뒤 원하는 sql명령을 처리해 db에 적용했습니다.</p>\n<p>하지만 flask는 보통 배포를 위해 사용되고 또한 배포되는 서버는 다수의 사용자가 사용하게 됩니다. 위와 같은 방식으로 구현한다면 1만명의 사용자가 접속했을 때 1만번의 db연결을 해줘야 됩니다.</p>\n<p>즉 매우매우 비효율적이고, 속도도 느립니다.</p>\n<p>이를 해결하기 위해 미리 db session을 저장해두는 pooling방식을 사용합니다.</p>\n<h3>flask-sqlalchemy</h3>\n<p>하지만 저희가 굳이 pooling을 구현할 필요는 없습니다. 이미 pooling방식으로 간단하게 데이터베이스를 연동할 수 있는 sqlalchemy 라이브러리가 존재하고,</p>\n<p>더 나아가 flask를 위해 구현되어 편리하게 app객체에 db옵션을 추가해줄 수 있고, 클라이언트 요청이 종료되면 자동으로 db_session을 pool에서 삭제시켜주기까지 하는\nflask-sqlalchemy라는 라이브러리가 존재합니다.</p>\n<h3>config</h3>\n<p><a href=\"https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/#configuration-keys\">https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/#configuration-keys</a></p>\n<p>flask-sqlalchemy 라이브러리를 사용하면 flask 객체에 sqlalchemy에 대한 설정을 해줄 수 있습니다.</p>\n<p>전체 config속성은 위 링크에 접속하셔서 확인해주시면 되고, 그 중 중요하다고 생각되는 기능들을 알아보겠습니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> flask <span class=\"token keyword\">import</span> Flask\n\napp <span class=\"token operator\">=</span> Flask<span class=\"token punctuation\">(</span>__name__<span class=\"token punctuation\">)</span>\n\napp<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">[</span><span class=\"token string\">'SQLALCHEMY_DATABASE_URI'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token string\">\"postgresql://{user_name}:{password}@{host}:{port}/{database_name}\"</span>\napp<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">[</span><span class=\"token string\">'SQLALCHEMY_COMMIT_ON_TEARDOWN'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token boolean\">True</span>\napp<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">[</span><span class=\"token string\">'SQLALCHEMY_POOL_SIZE'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">30</span>\napp<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">[</span><span class=\"token string\">'SQLALCHEMY_MAX_OVERFLOW'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">20</span>\napp<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">[</span><span class=\"token string\">'SQLALCHEMY_POOL_RECYCLE'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">60</span></code></pre></div>\n<p>사용법은 간단합니다. 생성된 flask객체의 config함수에서 원하는 속성값을 지정해주면 됩니다.</p>\n<ul>\n<li><code class=\"language-text\">SQLALCHEMY_DATABASE_URI</code>: 연결에 사용되는 데이터베이스 URI (어떤 sql을 사용하느냐에 따라 주소의 형태가 다릅니다.)</li>\n<li><code class=\"language-text\">SQLALCHEMY_COMMIT_ON_TEARDOWN</code>: 클라이언트의 request 마지막단에서 데이터베이스의 변경사항을 자동으로 커밋하는 기능</li>\n<li><code class=\"language-text\">SQLALCHEMY_POOL_SIZE</code>: pool 크기를 지정합니다.</li>\n<li><code class=\"language-text\">SQLALCHEMY_MAX_OVERFLOW</code>: pool overflow 크기를 지정합니다.</li>\n<li><code class=\"language-text\">SQLALCHEMY_POOL_RECYCLE</code>: pool에 존재하는 session이 자동으로 recycle되는 시간을 지정합니다.</li>\n</ul>\n<h3>db연결</h3>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> flask_sqlalchemy <span class=\"token keyword\">import</span> SQLAlchemy\n\ndb <span class=\"token operator\">=</span> SQLAlchemy<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\ndb<span class=\"token punctuation\">.</span>init_app<span class=\"token punctuation\">(</span>app<span class=\"token punctuation\">)</span></code></pre></div>\n<p>flask_sqlalchemy의 SQLAlchemy 클래스 객체를 생성해주고 init_app을 앞서 설정했던 flask app과 연결해주면 매우 쉽게 연동이 완료됩니다.</p>\n<p>자 이제 SQLAlchemy를 이용해 새로운 table을 생성해보겠습니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Test</span><span class=\"token punctuation\">(</span>db<span class=\"token punctuation\">.</span>Model<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    __tablename__ <span class=\"token operator\">=</span> <span class=\"token string\">'test'</span>\n    user_id <span class=\"token operator\">=</span> db<span class=\"token punctuation\">.</span>Column<span class=\"token punctuation\">(</span>db<span class=\"token punctuation\">.</span>String<span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> primary_key<span class=\"token operator\">=</span><span class=\"token boolean\">True</span><span class=\"token punctuation\">)</span>\n    name <span class=\"token operator\">=</span> db<span class=\"token punctuation\">.</span>Column<span class=\"token punctuation\">(</span>db<span class=\"token punctuation\">.</span>String<span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    \n    <span class=\"token keyword\">def</span> <span class=\"token function\">__init__</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">,</span> user_id<span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        self<span class=\"token punctuation\">.</span>user_id <span class=\"token operator\">=</span> user_id\n        self<span class=\"token punctuation\">.</span>name <span class=\"token operator\">=</span> name</code></pre></div>\n<p>db.Model 클래스를 상속받는 Test라는 클래스를 생성해봤습니다.</p>\n<p>이 Test클래스는 하나의 table입니다.</p>\n<p><code class=\"language-text\">__tablename__</code>: 이름에서 알 수 있듯이 테이블명입니다.</p>\n<p><code class=\"language-text\">user_id = db.Column(db.String(20), primary_key=True)</code>: user_id라는 컬럼을 만드는데 String type에 길이는 20이며, primary_key로 지정하겠다는 의미입니다.</p>\n<p>이런 식으로 원하는 테이블과 column들을 원하는 대로 만들어줄 수 있으며 자유롭게 코드 내부에서 객체로 생성해 사용가능합니다.</p>\n<p>다만 실제로 sql내부에 생성하려면 별도의 작업이 필요합니다.</p>\n<p>아까 db를 연결했던 코드에서 단 한줄만 추가해주면 됩니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> flask_sqlalchemy <span class=\"token keyword\">import</span> SQLAlchemy\n\ndb <span class=\"token operator\">=</span> SQLAlchemy<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\ndb<span class=\"token punctuation\">.</span>init_app<span class=\"token punctuation\">(</span>app<span class=\"token punctuation\">)</span>\ndb<span class=\"token punctuation\">.</span>create_all<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p><code class=\"language-text\">db.create_all()</code>을 사용하면 db.Model을 상속받은 클래스들이 실제로 sql내부에 존재하는지 여부를 확인하고 존재한다면 자동으로 생성해줍니다.</p>\n<h3>기본적인 db응용</h3>\n<p>SELECT</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">db<span class=\"token punctuation\">.</span>session<span class=\"token punctuation\">.</span>query<span class=\"token punctuation\">(</span>Test<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">all</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token comment\">#SELECT * FROM test</span>\ndb<span class=\"token punctuation\">.</span>session<span class=\"token punctuation\">.</span>query<span class=\"token punctuation\">(</span>Test<span class=\"token punctuation\">.</span>user_id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">all</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token comment\">#SELECT user_id FROM test</span></code></pre></div>\n<p>WHERE\n<code class=\"language-text\">filter</code>를 사용합니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">db<span class=\"token punctuation\">.</span>session<span class=\"token punctuation\">.</span>query<span class=\"token punctuation\">(</span>Test<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">filter</span><span class=\"token punctuation\">(</span>Test<span class=\"token punctuation\">.</span>user_id <span class=\"token operator\">==</span> <span class=\"token string\">'sooftware'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">all</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\ndb<span class=\"token punctuation\">.</span>session<span class=\"token punctuation\">.</span>query<span class=\"token punctuation\">(</span>Test<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">filter</span><span class=\"token punctuation\">(</span>Test<span class=\"token punctuation\">.</span>user_id <span class=\"token operator\">==</span> <span class=\"token string\">'sooftware'</span><span class=\"token punctuation\">,</span> Test<span class=\"token punctuation\">.</span>name <span class=\"token operator\">==</span> <span class=\"token string\">'Soohwan Kim'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">all</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> </code></pre></div>\n<p>INSERT</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">test <span class=\"token operator\">=</span> Test<span class=\"token punctuation\">(</span><span class=\"token string\">'sooftware'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'Soohwan Kim'</span><span class=\"token punctuation\">)</span>\ndb<span class=\"token punctuation\">.</span>session<span class=\"token punctuation\">.</span>add<span class=\"token punctuation\">(</span>test<span class=\"token punctuation\">)</span>\ndb<span class=\"token punctuation\">.</span>session<span class=\"token punctuation\">.</span>commit<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>sql에 대해 자세히 모르더라도 객체의 함수로 편리하고 쉽게 처리가 가능합니다.</p>","htmlAst":{"type":"root","children":[{"type":"element","tagName":"h2","properties":{},"children":[{"type":"text","value":"Flask"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Flask는 ‘micro’웹 프레임워크입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"즉 Django와 달리 최소한의 구성 요소와 요구 사항을 제공하기 때문에 시작하기 쉽고 필요에 따라 유연하게 사용할 수 있습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"하지만 완전한 기능을 갖춘 앱을 만들기에 제약이 있다는 뜻은 아니고 오히려 쉽게 확장할 수 있도록 설계되어 있습니다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"install"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"pip install flask"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"Hello Flask"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" flask "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" Flask\napp "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" Flask"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"__name__"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"  "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"# Flask 객체 생성"}]},{"type":"text","value":"\n \n"},{"type":"element","tagName":"span","properties":{"className":["token","decorator","annotation","punctuation"]},"children":[{"type":"text","value":"@app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"route"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"def"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"index"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'<h1>Hello World!</h1>'"}]},{"type":"text","value":"\n \n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" __name__ "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"__main__\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"run"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"debug"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"True"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" port"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"5000"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Flask를 처음 시작할 때 생성하는 hello world 출력 코드입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"정말 간단한 코드지만 Flask의 기본적인 구조를 잘 보여주고 있습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"app은 Flask객체입니다. 원하는 기능을 추가하고 싶을 때 이 app에 기능을 추가해주면되고, 특정 url에 기능을 추가하고 싶을 경우에도 app을 기준으로 url을 추가해준 뒤 기능을 구현해주면 됩니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"아무튼 이렇게 실행을 하면 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"app.run()"}]},{"type":"text","value":"을 통해 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"http://127.0.0.1:5000/"}]},{"type":"text","value":" 주소로 app이 배포가 시작됩니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"5000번 port는 flask에서 실행한 서버의 포트이며, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"debug=True"}]},{"type":"text","value":" 개발용으로 실행한다는 뜻으로 프로젝트에서 변경된 코드가 생길 시 자동으로 변경된 코드를 적용해서 서버를 다시 시작해주는 기능을 갖고 있습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"Route"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Flask를 사용시 어쩌면 가장 중요하다고 할 수 있는 route기능입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" flask "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" Flask\n\napp "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" Flask"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"__name__"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","decorator","annotation","punctuation"]},"children":[{"type":"text","value":"@app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"route"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","decorator","annotation","punctuation"]},"children":[{"type":"text","value":"@app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"route"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/home'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"def"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"home"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Hello, World!'"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","decorator","annotation","punctuation"]},"children":[{"type":"text","value":"@app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"route"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/user'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"def"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"user"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Hello, User!'"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" __name__ "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'__main__'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"run"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"debug"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"True"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"route는 말 그대로 경로를 지정해주는 기능입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이게 무슨말이냐. 보통 웹에 배포를 시작할 경우 다양한 기능들(로그인, 검색, 메뉴 등등)을 제공해야 하는데 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"http://127.0.0.1:5000/"}]},{"type":"text","value":" 이라는 주소 하나만으로는 모든 기능을 처리할 수 없습니다.\n그렇다고 저 주소안에 여러기능들을 다 쑤셔넣을 수도 없으니까요."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"app.route"}]},{"type":"text","value":" 데코레이터를 이용해 url의 suffix를 추가해줄 수 있습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"위에 코드를 예시로 들어보면 home 함수에는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/home"}]},{"type":"text","value":", "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"이라는 문자가 route 데코레이터를 통해 추가된 것을 확인할 수 있습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이 말은 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"http://127.0.0.1:5000/"}]},{"type":"text","value":" 또는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"http://127.0.0.1:5000/home"}]},{"type":"text","value":" 에 접속할 경우 home 함수를 실행하라는 뜻입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"마찬가지로 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"http://127.0.0.1:5000/user"}]},{"type":"text","value":" 에 접속 시 user함수가 실행되는 것을 알 수 있습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"Blueprint"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"굉장히 중요한 기능인 이 route는 기능이 필요할 때마다 계속 추가되어야 하기 때문에, 함수가 많을 경우 번거로워질 수 있습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"예를 들면 동일하게 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/menu"}]},{"type":"text","value":" 로 시작하는 url이 있는 경우 2~3개면 상관없겠지만 실제 프로젝트에선 10개가 넘어갈 수도 있는데 전부 하나씩 menu를 달아주는 것은 비효율적입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이런 상황에서 blueprint를 이용하면 route함수들을 보다 구조적으로 관리할 수 있게 됩니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"Blueprint 객체"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"# app.py"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" flask "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" Flask\n\napp "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" Flask"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"__name__"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"views "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" main_views\t\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"register_blueprint"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"main_views"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"bp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"# views\\main_views.py"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" flask "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" Blueprint\n\nbp "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" Blueprint"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'main_views'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" __name__"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" url_prefix"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/view'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","decorator","annotation","punctuation"]},"children":[{"type":"text","value":"@bp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"route"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/hello'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"def"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"main_view"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'main view'"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"blueprint 객체 생성"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Flask 객체 app에서 blueprint객체를 register해준다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"controller route에서 blueprint 객체를 써준다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"최종적으로 hello_pybo함수의 url은 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"127.0.0.1:5000/view/hello"}]},{"type":"text","value":"가 됩니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이런 식으로 blueprint를 사용하여 url을 구조적으로 관리해줄 수 있습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"app teardown appcontext"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","decorator","annotation","punctuation"]},"children":[{"type":"text","value":"@app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"teardown_appcontext"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"def"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"shutdown_session"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"exception"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"None"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    db_session"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"remove"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"app.teardown_appcontext"}]},{"type":"text","value":"데코레이터는 클라이언트의 요청이 종료됐을 경우에 자동으로 실행되도록 하는 함수입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"위 함수를 읽기만해도 알 수 있듯이 클라이언트의 요청이 종료될 경우 해당함수가 실행돼 db가 종료되도록 한다는 뜻입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"매우 간단하지만 중요한 개념이기 때문에 언급하고 넘어가겠습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{},"children":[{"type":"text","value":"Database"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이번엔 flask에 database를 연동하는 방법을 알아보겠습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"흔히들 python에 database에 연동할 때 각 sql을 지원하는 라이브러리의 connect()함수를 사용하여 연동했을겁니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"# ex) mysql 연결"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" pymysql \n\nconn "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" pymysql"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"connect"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    user"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'root'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" \n    passwd"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'{설정한 비밀번호}'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" \n    host"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'127.0.0.1'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" \n    db"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'juso-db'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" \n    charset"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'utf8'"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이런 식으로 간단하게 연동한 뒤 원하는 sql명령을 처리해 db에 적용했습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"하지만 flask는 보통 배포를 위해 사용되고 또한 배포되는 서버는 다수의 사용자가 사용하게 됩니다. 위와 같은 방식으로 구현한다면 1만명의 사용자가 접속했을 때 1만번의 db연결을 해줘야 됩니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"즉 매우매우 비효율적이고, 속도도 느립니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이를 해결하기 위해 미리 db session을 저장해두는 pooling방식을 사용합니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"flask-sqlalchemy"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"하지만 저희가 굳이 pooling을 구현할 필요는 없습니다. 이미 pooling방식으로 간단하게 데이터베이스를 연동할 수 있는 sqlalchemy 라이브러리가 존재하고,"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"더 나아가 flask를 위해 구현되어 편리하게 app객체에 db옵션을 추가해줄 수 있고, 클라이언트 요청이 종료되면 자동으로 db_session을 pool에서 삭제시켜주기까지 하는\nflask-sqlalchemy라는 라이브러리가 존재합니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"config"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/#configuration-keys"},"children":[{"type":"text","value":"https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/#configuration-keys"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"flask-sqlalchemy 라이브러리를 사용하면 flask 객체에 sqlalchemy에 대한 설정을 해줄 수 있습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"전체 config속성은 위 링크에 접속하셔서 확인해주시면 되고, 그 중 중요하다고 생각되는 기능들을 알아보겠습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" flask "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" Flask\n\napp "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" Flask"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"__name__"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"config"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SQLALCHEMY_DATABASE_URI'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"postgresql://{user_name}:{password}@{host}:{port}/{database_name}\""}]},{"type":"text","value":"\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"config"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SQLALCHEMY_COMMIT_ON_TEARDOWN'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"True"}]},{"type":"text","value":"\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"config"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SQLALCHEMY_POOL_SIZE'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"30"}]},{"type":"text","value":"\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"config"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SQLALCHEMY_MAX_OVERFLOW'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"20"}]},{"type":"text","value":"\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"config"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SQLALCHEMY_POOL_RECYCLE'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"60"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"사용법은 간단합니다. 생성된 flask객체의 config함수에서 원하는 속성값을 지정해주면 됩니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"SQLALCHEMY_DATABASE_URI"}]},{"type":"text","value":": 연결에 사용되는 데이터베이스 URI (어떤 sql을 사용하느냐에 따라 주소의 형태가 다릅니다.)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"SQLALCHEMY_COMMIT_ON_TEARDOWN"}]},{"type":"text","value":": 클라이언트의 request 마지막단에서 데이터베이스의 변경사항을 자동으로 커밋하는 기능"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"SQLALCHEMY_POOL_SIZE"}]},{"type":"text","value":": pool 크기를 지정합니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"SQLALCHEMY_MAX_OVERFLOW"}]},{"type":"text","value":": pool overflow 크기를 지정합니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"SQLALCHEMY_POOL_RECYCLE"}]},{"type":"text","value":": pool에 존재하는 session이 자동으로 recycle되는 시간을 지정합니다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"db연결"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" flask_sqlalchemy "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" SQLAlchemy\n\ndb "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" SQLAlchemy"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\ndb"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"init_app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"flask_sqlalchemy의 SQLAlchemy 클래스 객체를 생성해주고 init_app을 앞서 설정했던 flask app과 연결해주면 매우 쉽게 연동이 완료됩니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"자 이제 SQLAlchemy를 이용해 새로운 table을 생성해보겠습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"class"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Test"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"Model"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    __tablename__ "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'test'"}]},{"type":"text","value":"\n    user_id "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"Column"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"String"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"20"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" primary_key"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"True"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    name "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"Column"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"String"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"20"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    \n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"def"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"__init__"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"self"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" user_id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" name"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n        self"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"user_id "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" user_id\n        self"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" name"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"db.Model 클래스를 상속받는 Test라는 클래스를 생성해봤습니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이 Test클래스는 하나의 table입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"__tablename__"}]},{"type":"text","value":": 이름에서 알 수 있듯이 테이블명입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"user_id = db.Column(db.String(20), primary_key=True)"}]},{"type":"text","value":": user_id라는 컬럼을 만드는데 String type에 길이는 20이며, primary_key로 지정하겠다는 의미입니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이런 식으로 원하는 테이블과 column들을 원하는 대로 만들어줄 수 있으며 자유롭게 코드 내부에서 객체로 생성해 사용가능합니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"다만 실제로 sql내부에 생성하려면 별도의 작업이 필요합니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"아까 db를 연결했던 코드에서 단 한줄만 추가해주면 됩니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" flask_sqlalchemy "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" SQLAlchemy\n\ndb "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" SQLAlchemy"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\ndb"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"init_app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\ndb"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"create_all"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"db.create_all()"}]},{"type":"text","value":"을 사용하면 db.Model을 상속받은 클래스들이 실제로 sql내부에 존재하는지 여부를 확인하고 존재한다면 자동으로 생성해줍니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{},"children":[{"type":"text","value":"기본적인 db응용"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"SELECT"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"text","value":"db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"session"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"query"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"Test"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","builtin"]},"children":[{"type":"text","value":"all"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"#SELECT * FROM test"}]},{"type":"text","value":"\ndb"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"session"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"query"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"Test"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"user_id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","builtin"]},"children":[{"type":"text","value":"all"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"#SELECT user_id FROM test"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"WHERE\n"},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"filter"}]},{"type":"text","value":"를 사용합니다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"text","value":"db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"session"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"query"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"Test"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","builtin"]},"children":[{"type":"text","value":"filter"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"Test"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"user_id "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'sooftware'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","builtin"]},"children":[{"type":"text","value":"all"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\ndb"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"session"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"query"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"Test"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","builtin"]},"children":[{"type":"text","value":"filter"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"Test"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"user_id "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'sooftware'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" Test"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Soohwan Kim'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","builtin"]},"children":[{"type":"text","value":"all"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"INSERT"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"python"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-python"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-python"]},"children":[{"type":"text","value":"test "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" Test"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'sooftware'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Soohwan Kim'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\ndb"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"session"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"add"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"test"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\ndb"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"session"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"commit"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"sql에 대해 자세히 모르더라도 객체의 함수로 편리하고 쉽게 처리가 가능합니다."}]}],"data":{"quirksMode":false}},"excerpt":"Flask Flask는 ‘micro’웹 프레임워크입니다. 즉 Django…","fields":{"readingTime":{"text":"11 min read"}},"frontmatter":{"title":"Flask","userDate":"1 December 2021","date":"2021-12-01T10:00:00.000Z","tags":["toolkit","web","python","open-source"],"excerpt":null,"image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#080808","images":{"fallback":{"src":"/static/13c286ed78e56cb5a139e269d8eaea5f/fe339/flask.png","srcSet":"/static/13c286ed78e56cb5a139e269d8eaea5f/fe339/flask.png 452w","sizes":"100vw"},"sources":[{"srcSet":"/static/13c286ed78e56cb5a139e269d8eaea5f/fa21a/flask.webp 452w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":1}}},"author":[{"id":"Soohwan Kim","bio":"Co-founder/A.I. engineer at TUNiB.","avatar":{"children":[{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#282838","images":{"fallback":{"src":"/static/a9e6b445142b247ee4cfa66155398bb2/0d6f4/soohwan.png","srcSet":"/static/a9e6b445142b247ee4cfa66155398bb2/248f9/soohwan.png 40w,\n/static/a9e6b445142b247ee4cfa66155398bb2/fd435/soohwan.png 80w,\n/static/a9e6b445142b247ee4cfa66155398bb2/0d6f4/soohwan.png 120w","sizes":"100vw"},"sources":[{"srcSet":"/static/a9e6b445142b247ee4cfa66155398bb2/e7f45/soohwan.webp 40w,\n/static/a9e6b445142b247ee4cfa66155398bb2/589ec/soohwan.webp 80w,\n/static/a9e6b445142b247ee4cfa66155398bb2/71a38/soohwan.webp 120w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6833333333333333}}]}}]}},"relatedPosts":{"totalCount":25,"edges":[{"node":{"id":"f2a32d9d-b206-5141-8c2d-5440e19caf65","excerpt":"llama.cpp (On device llm inference tool) 최근에 llama.cpp를 사용해봤는데, 상당히 편리하고 미래에 더 많이 쓰일 툴이라는 생각이 들어서 기록해둔다! llama.cpp란? 대표적인 오픈소스 LLM인 Meta…","frontmatter":{"title":"llama.cpp (On device llm inference tool)","date":"2024-09-07T10:00:00.000Z"},"fields":{"readingTime":{"text":"7 min read"},"slug":"/llama-cpp/"}}},{"node":{"id":"fa28b462-1fe2-5d0f-932b-f28e32f1da18","excerpt":"Elastic Search logstash - Nori 토크나이저 설정 이번에 회사에서 검색 기능을 구현하면서 Elastic Search를 다루게 됐다. 이 엔진을 다루면서 삽질을 많이 했는데, 다음에는 하지 않도록 기록용으로 남겨둔다. Elastic…","frontmatter":{"title":"[ELK] Elastic Search logstash - Nori 토크나이저 설정","date":"2024-08-24T10:00:00.000Z"},"fields":{"readingTime":{"text":"4 min read"},"slug":"/elastic-search/"}}},{"node":{"id":"d1f4a9ee-591d-5e95-a930-a1bf17701b0e","excerpt":"단 30줄로 ChatGPT 웹페이지 만들기 (Streamlit chat_message) Streamlit은 파이썬 기반의 오픈소스 웹 UI 라이브러리입니다. 매우 간단한 코드로 손쉽게 웹페이지를 띄울 수 있어서 간단한 데모나 PoC…","frontmatter":{"title":"단 30줄로 ChatGPT 웹페이지 만들기 (Streamlit chat_message)","date":"2024-05-01T10:00:00.000Z"},"fields":{"readingTime":{"text":"9 min read"},"slug":"/streamlit-chatgpt/"}}},{"node":{"id":"4e37b604-dce8-5e09-85e8-337d4f03f0cb","excerpt":"Terabyte(TB) 단위 데이터 셔플링 - terashuf 리눅스에서 TB 단위의 데이터를 line 기준으로 셔플링이 필요할 때가 (가끔) 있다. 직접 코딩해서 쓰기에는 메모리, 속도 등을 신경써야해서 생각보다 큰 작업인데, terashuf…","frontmatter":{"title":"Terabyte(TB) 단위 데이터 셔플링 - terashuf","date":"2024-03-20T10:00:00.000Z"},"fields":{"readingTime":{"text":"1 min read"},"slug":"/terashuf/"}}},{"node":{"id":"ec8327c3-3c4d-51da-9440-8cb74fd1effe","excerpt":"tmux - conf Tmux 설정을 위한 tmux configuraion 기록","frontmatter":{"title":"tmux - conf","date":"2024-02-15T10:00:00.000Z"},"fields":{"readingTime":{"text":"2 min read"},"slug":"/tmux-conf/"}}}]}},"pageContext":{"slug":"/flask/","prev":{"excerpt":"# 총, 균, 쇠 (guns germs and steel…","frontmatter":{"title":"총, 균, 쇠 (guns germs and steel)","tags":["book","review"],"date":"2021-11-29T10:00:00.000Z","draft":false,"excerpt":null,"image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAYAAAD6S912AAAACXBIWXMAAAsTAAALEwEAmpwYAAAESUlEQVQ4y5VVW0ybZRguciqH0gLdhDm3bHLBQYXB0BlI9NYrsptxsyuNotxsUaPRLZkRAwlouGIMMTDOXSNUNAjYA0zCOJVif3AQiiC0tIUCPdBSeoDHfC/5K3X1wjd5833v93//8z3v877f/wuCwSCOjo7Aj/ycd34t5MHw56f3sVFwGoyNfr+fPBAIIBDwh8WRDj19CJsL+AfHx8ew2WwwbhjDDvD5fPB6vfB4PHC73TSymD07OTQQdkgYoHnTDJnsEdbW1hDJAv4A9l0uOBwOLC0twWQy0dxhd0RmyACHhoZoE7NHcjk6u7rBcfMYHx/H0uISDr1eykShUKCmpgYbGxsEyDMNATIzLC+jva0dU1NTFKsHf8IPPR2QdbajrrYW1dXVUKvUWFhYgEwmQ1VVFVQqFex7e+EMGTqzp388RUd7B1ZXVyk+cNnh3XfA5z5h7HF7sGW1YmVlBXK5HA8eNGF0dBRWqzWyhpubmxj8ZRDbtm0C2N2zY0arBTc/T1L4Dg9D2YyMjEDR10cpu5yuZ1MmDc1maNRqqiarrk6nw+zsLMbGxtDW1gaL2Uwp1n3zLZRKFfnjx79hd/c/Up6bm0Pj/Ubo9XqK19fX0dLSgtbWVvT29mL1z1WMqH5Fe/N9yDsforvjIb5vaoycMgH8tQ6VUoWdnR2KmVZdXV0khcFgoLVDr4d0tdusMG+sQa/TYsdme7ZtmLG+YtWzWCwUHwWD0Gq1xHxychLegwM4nU74AwGoNSNQKH5EV3cPrBZrqLnDi2LaBKfn6CVmW9vbMBpNWDYYSPzFxUXs7+/DbreTBP39/Whubqa+jKih/nc96uvrqRjMvmtqxN0vPsPXVV9Rz9XV1UGpVILjOAwMDEDRpyCNGcOIKW9tbWGe4+ByuSj2u/fg3jHB49zFoc8Hp8NBchiNRmLMMtFoNMQ4IsPh4WFq1icTE6Td9PQMpqam6ebMzGihZa6dJWfxxMQktY5ON3dSZR6QfZ6YVVS8D4FAgMQEIblUIkKGVAJpagrSJSlIFScjTSyi+EyaGOefl0KcJERpSQm9H2obHvDTTz7GOYkQElEioqOiIEqIR2qyEOKkeGSkiXBWkoT0lESkixIgSohDkjCWCOTnv/oPIKPKA96+dQsS4XNIFyfTxkgeFSVAdHQ0omNiEBsXT2uFhUXhDNlHk121DysqIIqLQlxsDDKlKai/fR0fXH8DmZmZKLxyBQUF+cjJzsbLeXnIzc3FteIiFBW8gpLS0vCbwqpq27ah/MaNEJObb78Ow8+1GGr4CBfOnUVu1kWU5GfhavYFFGefx7WcF5B3UUp7X8rKipzy3Tt3QoBpSTH4/OabeCv/xdBajEBAuqUkJyLjTDouX7qEnNw8VFZWhqfM3xTWPqxxy8vLcbX4NZSVleGdd9/DvXtfoqGhAT0yGVRqDfR6DmazhaTiezjsr3f6z/d/7d9/wL8B68MRMwJJKHoAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/1c8939ae20fc1d70759ddc0713974d78/a9b4b/ggs.png","srcSet":"/static/1c8939ae20fc1d70759ddc0713974d78/a9b4b/ggs.png 458w","sizes":"100vw"},"sources":[{"srcSet":"/static/1c8939ae20fc1d70759ddc0713974d78/d2c19/ggs.webp 458w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":1.1855895196506552}}},"author":[{"id":"Soohwan Kim","bio":"Co-founder/A.I. engineer at TUNiB.","avatar":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAADjElEQVQ4y23Oy48TdQDA8TExEaTttvSBfdHddru7bWc6bWd+8+i0u23n0SdlBRQXZGHDgiiLDwgqXjCIJEaC8cLBmHgwUU9EYzRqQuLJi/4NJB6NF+8evgbOHr7XT76SM5ix7s4QnRHnnm9yZzvBTIswN8JcP5bC67ZoWi7CdtFsn5bloZo+dSNAMYbIIqCmD6mJIVXdR3J6I7r9IQ3T59pZlW+uxzndCbPdC/HZXoq3TikowsfqBOjOmFZ7SrM9p2kfRbXn1O0jKNbsSbJ5BMnu9Gl3+qiiz4OPSvz0QRLHFGwOZH6+neLHT5YRbRerM0J0JrTas/8FZXNKzZgg2es+ZtvDdbs8+iHJl+9lWVP7OG2br26k+PvXJCfmFqoYIpwhTXtMwxpTN0coxhjFmCKbE2rGmKoYPQY9qi2fyzsq//4e5sNXi5TlLqbd5t6lPH/9kuDTG2usqgGi7dO0hzSsIXUzQDaGKGKMLEZUxZCKCJB02+PUpMH9vQwP7ybYnSxyfNrjwumA3dEiD94v8cfnK7xzWsbpujQtH9X0qBs+iuEjC5+a7lPVPSqai9SyelyYFbjkh5hqC3TkKOutLON2nkYpgtuMcT6IszdPslo8SLlcpmUH1A0XRQyQhUtNuFQ1l4o2QFI1h3OTVXbcg+grIfSVBRqlEGopgrYSRi0e4KiIse1mScSeopA/iLADmoZL3Rgg631q+oCq1qeq95FOzhQefpzn7eMpBmqcoBVj04pzwkky0eNMRYIdL8F3twusLe2nslrE6g5pGX1U8/FhD1nvUW1tUJK7SH9+n+DR1zF2vQSvH0lz88wiV45V2J1WuHqsxLXNAnuzNJdfWmK5/BylUgFhb6DZAxR9g7rpIos+Wttja2uE9M9vYb69k+DqfJErWzLOuoVqdKlpDo4jODms4zlFckuHObx4iHwuRi6fYqmYY201x/LqMrnFDNl8gRvvukhNdT9394rcOlNFMxrUhYFmW9imTEsp0mhWKC2nWSokyWSiFA7HSKcXiEb34fayyLVniUQk8rmn2drKIqlqiNcuVrh2ymQS1Nh8sc/GoMEbl7u8eb5D1yqTzkRJJsOkkiGymQVShyLE4yHWKnEq1RjpTIhmI8r2y3mkyloI38uha1n6bpVXrkw5+4LD/S/2uHnrIopaJhZ9hmQqwqHkAXJP8BDhyD46ZoWdMxOGcx/PNfECk/8AbxXdRjRliPoAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/a9e6b445142b247ee4cfa66155398bb2/7cf1f/soohwan.png","srcSet":"/static/a9e6b445142b247ee4cfa66155398bb2/34f77/soohwan.png 750w,\n/static/a9e6b445142b247ee4cfa66155398bb2/a94f6/soohwan.png 1080w,\n/static/a9e6b445142b247ee4cfa66155398bb2/7cf1f/soohwan.png 1148w","sizes":"100vw"},"sources":[{"srcSet":"/static/a9e6b445142b247ee4cfa66155398bb2/38420/soohwan.webp 750w,\n/static/a9e6b445142b247ee4cfa66155398bb2/7470d/soohwan.webp 1080w,\n/static/a9e6b445142b247ee4cfa66155398bb2/b5ef6/soohwan.webp 1148w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6829268292682927}}}}]},"fields":{"readingTime":{"text":"5 min read"},"layout":"","slug":"/guns-germs-and-steel/"}},"next":{"excerpt":"K(orea) Startups Intro 한국에 있는 테크 스타트업들 리스트와 간단한 설명을 기록합니다. ‘내가 아는 스타트업들이 얼마나 될까?’ 라는 간단한 생각을 시작으로 기록하게 됐습니다. 허훈님의 nlp-startups, 염기웅님의 Korea…","frontmatter":{"title":"K-Startups (Korea AI Startups)","tags":["record"],"date":"2021-12-05T10:00:00.000Z","draft":false,"excerpt":null,"image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAChklEQVQoz3WT3UuTURzH9y90WQleSHRRISmx4evzTMWLJIKIEoxuuqk/oUjoIgiDSDJ7W5YvY5K5ufdpmIg6tWdOzYxS5151e/ZMSzC6CPrE82zTSXVxON9zzu98z+93ft+vTnDLiB4ZwZNG1HAa0aug7gu59V9YnV0pLV4o3POk0RUGqrNRPXQkMKo4f1F9JIeNvgyieu6II9ii1LlTCB4lm4xbzhLmyaqcKUTrOnrzZyocSeo9MrX2ODXOJNVvVqnuW8LQu0SlNcJRc5gjfWGKTEvU2BN7SelUVjUTvT3Fzakkn9K7NNrDFD+RtEwb7FFO94co7ZrnTMd7xG6Jokd+LvbP0dI1yimThL5/BaNrc7/keq9CmS3JjeE1/IF5zrljXPBt0DaTwGCNITo3afZEaHrtp/GVn8OdEtU9QRofD1NsWqTClfuebMlprbTSgSgt1o+0j8xxL7jFUynGg9kEbYvf6Qn9xPY1w4uJZbqDcW5Np2gdW8WyLHM3oFA7uI7gSmpl67RGOBLoB8LckTKs7/7m/vgKrWYvJvc4/ojCbPIHY9Ed2he2eLaoMBLZYWwtzcL2L24HtikzSRidBSWrMql2bHLeE+f62Ablli+cfTlBU/c0zb2TXLZI1FmWaOwNcHUgyCVXiCujKa5NfcNgjVM1FN9vyl6X3TI1LhnBmaT0bYxKa5QK8zLlD99R2bNASecMxzsmOdbp51DbKAbzMkZbJCspTTpZHevEHBByWmvwKdT7FIxeJRs8FEUYXKfOuYFxMMRJyxolpnlOPP9AnSOBkDNBnkMnFKr9H0P9Ds05moMy1Lhl9E75AIlYYA7dngvyttPG/x8Rcw4Sc1YTD9xL8wcjuLOuXOFpNAAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/bb766eb0837f5b7957ea04f792e7cab4/d2fbe/startup.png","srcSet":"/static/bb766eb0837f5b7957ea04f792e7cab4/2512b/startup.png 750w,\n/static/bb766eb0837f5b7957ea04f792e7cab4/45604/startup.png 1080w,\n/static/bb766eb0837f5b7957ea04f792e7cab4/8b6b1/startup.png 1366w,\n/static/bb766eb0837f5b7957ea04f792e7cab4/d2fbe/startup.png 1600w","sizes":"100vw"},"sources":[{"srcSet":"/static/bb766eb0837f5b7957ea04f792e7cab4/80f13/startup.webp 750w,\n/static/bb766eb0837f5b7957ea04f792e7cab4/4f9a6/startup.webp 1080w,\n/static/bb766eb0837f5b7957ea04f792e7cab4/af4ab/startup.webp 1366w,\n/static/bb766eb0837f5b7957ea04f792e7cab4/d0dfe/startup.webp 1600w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6}}},"author":[{"id":"Soohwan Kim","bio":"Co-founder/A.I. engineer at TUNiB.","avatar":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAADjElEQVQ4y23Oy48TdQDA8TExEaTttvSBfdHddru7bWc6bWd+8+i0u23n0SdlBRQXZGHDgiiLDwgqXjCIJEaC8cLBmHgwUU9EYzRqQuLJi/4NJB6NF+8evgbOHr7XT76SM5ix7s4QnRHnnm9yZzvBTIswN8JcP5bC67ZoWi7CdtFsn5bloZo+dSNAMYbIIqCmD6mJIVXdR3J6I7r9IQ3T59pZlW+uxzndCbPdC/HZXoq3TikowsfqBOjOmFZ7SrM9p2kfRbXn1O0jKNbsSbJ5BMnu9Gl3+qiiz4OPSvz0QRLHFGwOZH6+neLHT5YRbRerM0J0JrTas/8FZXNKzZgg2es+ZtvDdbs8+iHJl+9lWVP7OG2br26k+PvXJCfmFqoYIpwhTXtMwxpTN0coxhjFmCKbE2rGmKoYPQY9qi2fyzsq//4e5sNXi5TlLqbd5t6lPH/9kuDTG2usqgGi7dO0hzSsIXUzQDaGKGKMLEZUxZCKCJB02+PUpMH9vQwP7ybYnSxyfNrjwumA3dEiD94v8cfnK7xzWsbpujQtH9X0qBs+iuEjC5+a7lPVPSqai9SyelyYFbjkh5hqC3TkKOutLON2nkYpgtuMcT6IszdPslo8SLlcpmUH1A0XRQyQhUtNuFQ1l4o2QFI1h3OTVXbcg+grIfSVBRqlEGopgrYSRi0e4KiIse1mScSeopA/iLADmoZL3Rgg631q+oCq1qeq95FOzhQefpzn7eMpBmqcoBVj04pzwkky0eNMRYIdL8F3twusLe2nslrE6g5pGX1U8/FhD1nvUW1tUJK7SH9+n+DR1zF2vQSvH0lz88wiV45V2J1WuHqsxLXNAnuzNJdfWmK5/BylUgFhb6DZAxR9g7rpIos+Wttja2uE9M9vYb69k+DqfJErWzLOuoVqdKlpDo4jODms4zlFckuHObx4iHwuRi6fYqmYY201x/LqMrnFDNl8gRvvukhNdT9394rcOlNFMxrUhYFmW9imTEsp0mhWKC2nWSokyWSiFA7HSKcXiEb34fayyLVniUQk8rmn2drKIqlqiNcuVrh2ymQS1Nh8sc/GoMEbl7u8eb5D1yqTzkRJJsOkkiGymQVShyLE4yHWKnEq1RjpTIhmI8r2y3mkyloI38uha1n6bpVXrkw5+4LD/S/2uHnrIopaJhZ9hmQqwqHkAXJP8BDhyD46ZoWdMxOGcx/PNfECk/8AbxXdRjRliPoAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/a9e6b445142b247ee4cfa66155398bb2/7cf1f/soohwan.png","srcSet":"/static/a9e6b445142b247ee4cfa66155398bb2/34f77/soohwan.png 750w,\n/static/a9e6b445142b247ee4cfa66155398bb2/a94f6/soohwan.png 1080w,\n/static/a9e6b445142b247ee4cfa66155398bb2/7cf1f/soohwan.png 1148w","sizes":"100vw"},"sources":[{"srcSet":"/static/a9e6b445142b247ee4cfa66155398bb2/38420/soohwan.webp 750w,\n/static/a9e6b445142b247ee4cfa66155398bb2/7470d/soohwan.webp 1080w,\n/static/a9e6b445142b247ee4cfa66155398bb2/b5ef6/soohwan.webp 1148w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6829268292682927}}}}]},"fields":{"readingTime":{"text":"26 min read"},"layout":"","slug":"/k-startups/"}},"primaryTag":"toolkit"}},
    "staticQueryHashes": ["3170763342","3229353822"]}