# sqllite의 경우 Alter문에 대해 모듈이 지원하지않음
# 그러므로 MetaData 클래스를 사용하여 규칙을 정의해야하므로 설정시 옵션 render_as_batch=True을 추가해야함
ERROR [root] Error: No support for ALTER of constraints in SQLite dialectPlease refer to the batch mode feature which allows for SQLite migrations using a copy-and-move strategy.
flask DB 관련 주요 Command 정리 (flask db –help) 및 관련 에러
명령
의미
branches
현재 브랜치의 지점을 보여줍니다
current
각 DB의 현재 형상을 보여줍니다
downgrade
DB를 이전 버전으로 변경
upgrade
DB를 최신 버전으로 변경
edit
형상 파일 수정
heads
Show current available heads in the script directory
history
변경내역 조회
init
새로운 마이그레이션 생성
list-templates
List available templates
merge
두 형상 파일 병합
migrate
형상 파일 자동 생성
revision
형상 파일 생성
show
Show the revision denoted by the given symbol
stamp
‘stamp’ the revision table with the given revision
# 마이그레이션 repository 생성
flask db init
이 과정에서 생성된 테이블 (alembic_version)은 현재 자신의 db 버전을 가리키기 위해 생성되는 테이블
# 현재 DB 형상 확인
flask db current
# 현재 형상 마이그레이션 생성
# 메시지는 " 쌍따옴표를 쓰도록하자 '은 에러나는 경우있음
flask db migrate -m "Init database"
# 바뀐 DB 형상 내용을 DB에 적용
flask db upgrade
# 어떠한 오류로 upgrade와 migrate가 안될때
# ex) Cannot Add Foreign Key Constraint 에러 발생
# 잘못된 칼럼 타입을 넣고 foreign key를 생성하려하니 upgrade가 안되는 상황
# 변경하려해도 이미 잘못된 타입을 migrate한 상태라 upgrade가 안되고
# downgrade 후 migrate 진행시 [Target database is not up to date.] 에러로 역시 안될때
flask db stamp head
# head에서 다시 migrate
flask db migrate
# pymysql 모듈을 추가했는지 확인해보자
ModuleNotFoundError: No module named 'MySQLdb'
# mysql이 동작하는지 연결정보는 확인해보자
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([WinError 10061] 대상 컴퓨터에서 연결을 거부했으므
로 연결하지 못했습니다)")
# model a 내부에 선언된 상태
table_b = db.relationship(
'model_name', # 연관된 모델 지정
secondary=tabel_name, # 다대다 관계 테이블을 참조
# model a에서 b를 참조하듯 b에서도 a를 참조할 수 있도록 선언
backref=db.backref('table_a')
)
# 사용 예시
from [model_path] import Model_A
from [model_path] import Model_B
Model_A.query.first().table_b
Model_B.query.first().table_a
추가) DB 테이블 모델화 예시
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'user'
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.String(20), unique=True, nullable=False)
user_name = db.Column(db.String(20), nullable=False)
password = db.Column(db.String(100), nullable=False)
joindate = db.Column(db.DateTime, default=datetime.utcnow())
def __init__(self, user_id, user_name, password) -> None:
self.user_id = user_id
self.user_name = user_name
self.password = password
@classmethod
def find_one_by_user_id(cls, user_id):
return User.query.filter_by(user_id=user_id).first()
def as_dict(self):
return {x.name: getattr(self, x.name) for x in self.__table__.columns}
쿼리 (Query) 사용법
from app_name import db
from app_name.models.user import User
from app_name.models.payment import Payment
Select – 검색
# 쿼리 확인
print(User.query)
# select * from user;
User.query.all()
# select * from user limit 0, 1;
User.query.first()
# primary key 값 검색
# select * from user where id = 3;
User.query.get(3)
# 검색 내용이 없을 경우 404 처리
User.query.get_or_404(3)
# LIMIT절
# select * from user limit 0, 2;
User.query.limit(2).all()
# Where절 + Like절 = select * from user where user_name like 'jpro%';
User.query.filter(User.user_name.like('jpro%')).all()