MySQL Workbench를 이용해서 쉽게 기존 DB SCHEMA 그대로 새로 SCHEMA 생성하기

이미지
1. MySQL Workbench에서 Model 메뉴 진입 2. Reverse Engineer 선택 3. 복제할 대상의 Schema를 선택 후 모든 option next 대충 이런식의 모델이 생성된다. 4. 이 상태에서 그대로 Forward Engineering 5. 적절하게 원하는 옵션선택해주고 나면 마지막에 대략 이런 SQL문이 만들어진다. 이걸 실행하지는 말고  만들어진 내용만 복사하자.  DB명을 새로 만들 DB명으로 변경해줘야 하니까. 스샷 기준으로는 abmgt_prod를 my_new_table_name으로 변경하면 되겠다. 그대로 안되고 에러나는 경우가 있다. MySQL 버전차이로 생기는 문제일 수 있고 문제의 원인은 다양한데 내 경우엔 2가지 이슈가 있었다.  1. Date에 0000-00-00과 같은 값이 허용되지 않음. 3번째 줄 SQL_MODE의 String에 ,ALLOW_INVALID_DATES 를 추가하니까 해결. 2. UNIQUE INDEX 생성 구문 에러 MySQL 버전따라서 `Unique INDEX(id).. VISIBLE)` 이런 곳에서 에러가 날 수 있다.  MySQL 버전차이 때문에 그럴텐데 VISIBLE 혹은 INVISIBLE을 없애거나 꼭 사용하는데 필요하다면 MySQL의 버전을 올리던가 해야한다. 

AWS Lambda로 Excel -> PDF 변환 기능 개발 후기

이미지
요즘엔 서버리스로 개발하는 회사에서 근무중이다. 쓸 수록 느끼지만 서버리스는 간단한 메시지 전달은 좋지만 점점 서비스가 커지면 느껴지는 제약들이 많다. 그 때는 정말 '아 이거 서버 놓고 하면 금방인데 ㅠㅠ' 하는 생각이 절로든다.. 거기다가 Amplify가 아직 성숙하지 않아서 (=버그가 많다) 버전업하면 갑자기 배포가 안되고 그러는 경우도 종종 있다. 아무튼 이번엔 서버리스 환경에서 (=AWS Lambda) 에서 PDF를 Excel로 변환하는 업무가 주어져서 많은 삽질 끝에 해내게 되었다. 즉 이 글은  AWS Lambda에서 Libreoffice를 이 용해 xlsx 파일을 pdf로 변환하는 기능을 구현하던 중 겪은 어려움과 주의사항 에 대해 기술한다. 실제 구현 방법은 아니고 겪은 Trouble이니 실제 구현을 기대한다면 미리 기대에 어긋난다고 이야기 하고 싶다. 문제 1.람다에서 Streaming으로 Response를 제공할 수 없다. 많은 사람들이 아마 API Gateway와 Lambda를 연동해서 사용할 것이다. 우리도 역시 그렇게 활용중인데 Lambda의 특징은 응답을 한번 보내면 종료된다는 것이다.  일반적으로 웹에서 파일을 다운로드 받을 때는 Streaming으로 받아서 현재 다운로드 되는 현황을 구경할 수 있는데 Lambda로는 그렇게 구현하는 방법을 찾지 못했다. 따라서 서버에서 컨버팅 작업을 모두 끝내고 파일이 생성되면 해당 파일의 Binary를 String으로 변환하고, 이 String을 Response의 Body에 담아 보내게 했다. Client는 받은 String을 다시 Binary로 변환해서 이를 다운로드 하게 만들었다. 당연히 파일의 수가 많아질수록 변환하는데 시간은 더 걸릴 것이다.  API Gateway를 잘 customize하면 Streaming도 대응할 수 있는 것 같은데 확실하지 않다. 그리고 중요한 것. Lambda에서 타임아웃을 길게 걸어놔도 Request를 받은 API Gateway...

실용주의 프로그래머 key takeaway for myself.

1장 깨진 창문을 그대로 두지말자. 깨진 창문에는 Not Implemented 혹은 Dummy data를 추가하는 방식으로 구현해둘 것. 카펫을 더럽히는 일(기존 코드를 바꾸는 작업)은 필요한 순간이 온다. 카펫을 더럽히기 싫어서 가던 곳으로 가지 말고 필요하다면 과감하게 바꿀 것. 적당히 괜찮은 것이 늦어지는 것보다 낫다. 약간의 버그를 감내하더라도 그걸 다듬는다고 망치지마라. 언제 멈춰야할지를 알자.어차피 완벽한 코드란 없다. 지식이란 투자 포트폴리오와 같다. 지식을 다각화하고 (한 분야의 외골수보다 다양한 분야로) 계속해서 투자(계속해서 공부할 것)하며 리턴과 리스크의 조정을 적절히 하고 (기술 배울 때 선택) 주기적으로 재점검 하자. - one new language per year - 기술서적을 분기마다 하나씩. (볼 것을 좀 정해두면 좋겠다) 소통도 분위기를 파악해가며 하자. 말을 하기 전에 미리 적절히 정리해놓을 것. 말할 타이밍을 잘 계산하고 말할 것. 2장 강력하게 Coupling 된 Task는 하나만 해도 다른 하나가 업데이트 되도록 자동화를 시켜두자. 테스트 코드가 문서에 따라 자동으로 만들어지는 사례가 있었다. 만약 문서와 코드의 관계가 깊게 coupling 된 관계라면 문서 혹은 코드를 업데이트할 때 이와 관련 된 작업 혹은 the other one도 똑같이 자동으로 업데이트 할 수 있도록 개선하자. 직교성(Orthogonality)은 중요하다. 프로그래밍에서 직교한다라는 말은 하나가 수정되어도 다른 것에 영향을 주지않는다는 의미로 Decoupled 상태라고 볼 수 있다. 회의에서 직교성을 살펴보는 방법도 재미있다. 어떤 주제로 회의를 하려고 할 때 불러야 하는 사람 수가 많아질수록 직교성이 낮다는 것을 의미한다. 잘못 된 객체지향 코드는 때때로 절차지향 코드보다도 더욱 더 스파게티 코드가 될 확률이 높다. 예광탄 코드를 먼저 쏘아올리자. POC(Proof Of Concept)와 비슷하지만 좀 더 큰 개념. 동일한 환경과 제약을 가진채 ...

WebSocket - 예엣날에 공부했던 내용 정리

# Websocket WebSocket Tutorial with Python 웹소켓이란, HTTP 프로토콜의 단점을 극복하고 실시간 full duplex통신을 위한 기술이다. 개인적으로 웹소켓의 핵심은 Real-time dataflow라 생각한다. 1. 웹소켓이 맺어지는 흐름 Client가 TCP/IP 요청을 보내면 서버에서 TCP/IP 요청을 수락한다. 그 후 Client는 서버에게 웹소켓 handshake를 요청하고 서버는 이를 수락한다. 이렇게 하면 http에서 websocket으로 프로토콜이 전환되며 connection이 만들어지고  이 때부터 웹소켓을 통해 데이터를 송, 수신한다. * 웹소켓은 Http와 전혀 다르다. 다만 웹소켓을 만드는데에 http가 개입을 하는 것이다. 웹소켓이 만들어지면 서버는 응답코드 101을 보낸다. (101은 프로토콜이 전환되었음을 알리는 응답코드다) 2. 웹소켓은 왜 쓰는 것인가? Http보다 더 나은 점이 있을테니 websocket을 쓸텐데 그 점은 무엇일까? 그걸 알기 위해서는 일단 비동기 http 통신방식인 Ajax(XMLHttpRequest, 이하 htttp)에 대해 좀 알아야 한다. AJAX의 본래 이름은 XMLhttprequest이다. 이 기술이 나오고 비동기 통신이 팍! 떡상했다. 하지만 http엔 단점이 있다. 크로스 오리진 문제와 헤더의 용량 문제다. 3. 웹소켓이 http보다 더 나은 점은? 웹소켓과 비교하면 http통신은 항상 요청헤더가 부여되기 때문에 1바이트의 정보를 송신하고 싶어도 수킬로바이트에 달하는 쓸모없는 정보를 보내야한다. "에이 1바이트를 보낼 일이 언제 있다고" 하는 생각이 먼저 들었는데, 생각해보면 채팅같은 경우엔 말을 짧게 짧게 보내기도 한다.  "ok" 보내면 겨우 2바이트다. 이걸 매번 http로 통신한다면 저 짧은 두 글자를 보내는데도 많은 트래픽이 소요될 것이고 이는 성능의 문제로 귀결될 것이다. Real-time application에서는...

생산수단은 반드시 필요하다

자본주의에서 부유 계층에 속하는지 아닌지 는 결국 생산수단을 소유하는가에 달려있다. 생산수단이 만들어내는 생산물을 받는 입장일지라도 양이 크다면 일시적으로 부유해질 수 있지만 최대 본인 세대까지 넉넉하게 살 수 있을 듯하다. 일시적 부가 아닌 부유 계층에 속하기 위해서는 생산수단을 소유하는 것이 중요하다. 일생을 살며, pay라는 동사가 능동태가 아닌 수동태로만 쓰여진다면 나와 내 후세대는 절대로 돈에서 자유로워 질 수 없을 것이다. 삶은 많은 경험과 도전과제들이 있다. 돈 때문에 이런 것들을 포기해야 한다면 안타까울 것이다. 그래서 부유한 삶 그 자체가 목표가 아니고 부유하기 때문에 다양한 것을 시도하고 실패할 수 있는 삶을 추구한다.  먹고사니즘에 얽매여 내 삶의 범위를, 자유를 한정짓지 않도록 언젠가 반드시 생산수단은 소유해야한다. 개발자라는 직업은 다른 직업보다 수월하게 본인의 지식과 실력을 생산수단으로 만들 수 있다. 완전한 생산수단이라기 보다는 반(半) 생산수단이라고 보는 것이 합당할 것 같다. 좀 더 발전하여 내 스스로가 완전한 반(半) 생산수단이 되고 나아가 생산수단을 소유할 수 있는 삶을 살 수 있기를.

2020.04.27 TIL 스프링 - Spring Form Tag 사용하기

Spring의 form 태그는 이렇게 prefix를 붙이고 modelAttribute를 추가하여 사용한다. <form:form modelAttribute="student">   <form:input path="name">    // 자동으로 student모델의 getName()의 값이 초기 값으로 세팅되고, 이후에 submit을 하면 setName()이 호출된다. 언제나 case 유의할 것! 처음에 모델을 포함해서 HTML을 렌더링 해주는 controller는 아래와 같이 사용한다. ``` @RequestMapping("/showForm") public String showForm(Model theModel) { Student theStudent = new Student(); theModel.addAttribute("student", theStudent); theModel.addAttribute("theCountryOptions", countryOptions); return "student-form"; } ``` HTML 코드는 이러하고 ``` <form:form action="processForm" modelAttribute="student"> Student first name: <form:input path="firstName"/><br> Student last name: <form:input path="lastName"/><br> <form:select path="country"> <form:options items="${theCountryOptions}"/> </for...

2020.04.25 TIL 스프링 - XML 없이 Configuration 하기

## Configuration 클래스 작성 1. Create java class with @Configuration, @ComponentScan annotation @Configuration @ComponentScan(PACKAGE_NAME) public class MyConfig {} 2. Load Config class context at main file. main { AnnotationConfigApplicationContext context =   new AnnotationConfigApplicationContext(MyConfig.class); } ## Bean도 SpringContainer Config안에서 만들기 1. Config Class에서 @Bean annotation으로 바로 Bean을 주입할 수 있다. - 사전에 필요한 사항은 Bean 클래스가 구현할 인터페이스, Bean 클래스이다. @Configuration public class MyConfig() {   @Bean   public Something something() {     // 이 때 MySomething이 Bean으로 동작할 클래스로, Something을 구현하고 존재하고 있어야 함.     return new MySomething();   }   @Bean   public Another another() {     // 이 때 MyAnother Bean은 something을 inject 받는 Bean이다.     return new MyAnother(something());  //   } } ## Full Code ``` Main public class SwimJavaConfigDemoApp { public static void main(Stri...