기존 매핑 된 클래스에 필드를 추가하고 싶습니다. 어떻게 자동으로 sql 테이블을 업데이트합니까? 필드가 클래스에 추가되면 sqlalchemy는 데이터베이스를 새 열로 업데이트하는 메소드를 제공합니다.SqlAlchemy 클래스에 새 필드 추가 및 테이블에 해당 열 만들기
11
A
답변
5
SQLAlchemy 자체는 스키마의 자동 업데이트를 지원하지 않지만 마이그레이션을 자동화하는 타사 SQLAlchemy Migrate 도구가 있습니다. 그것이 작동하는 방법을 보려면 "Database schema versioning workflow" chapter을보십시오.
9
때때로 마이그레이션은 너무 많은 작업입니다. 변경된 코드를 실행할 때 열을 자동으로 추가하려고합니다. 그래서 여기에 그 기능이 있습니다.
주의 사항 : SQLAlchemy 내부에서 발생하며 SQLAlchemy가 주요 수정 사항을받을 때마다 작은 변경이 필요합니다. (아마도 SQLAlchemy 전문가가 아닙니다.) 또한 제약 조건도 처리하지 않습니다.
import logging
import re
import sqlalchemy
from sqlalchemy import MetaData, Table, exceptions
import sqlalchemy.engine.ddl
_new_sa_ddl = sqlalchemy.__version__.startswith('0.7')
def create_and_upgrade(engine, metadata):
"""For each table in metadata, if it is not in the database then create it.
If it is in the database then add any missing columns and warn about any columns
whose spec has changed"""
db_metadata = MetaData()
db_metadata.bind = engine
for model_table in metadata.sorted_tables:
try:
db_table = Table(model_table.name, db_metadata, autoload=True)
except exceptions.NoSuchTableError:
logging.info('Creating table %s' % model_table.name)
model_table.create(bind=engine)
else:
if _new_sa_ddl:
ddl_c = engine.dialect.ddl_compiler(engine.dialect, None)
else:
# 0.6
ddl_c = engine.dialect.ddl_compiler(engine.dialect, db_table)
# else:
# 0.5
# ddl_c = engine.dialect.schemagenerator(engine.dialect, engine.contextual_connect())
logging.debug('Table %s already exists. Checking for missing columns' % model_table.name)
model_columns = _column_names(model_table)
db_columns = _column_names(db_table)
to_create = model_columns - db_columns
to_remove = db_columns - model_columns
to_check = db_columns.intersection(model_columns)
for c in to_create:
model_column = getattr(model_table.c, c)
logging.info('Adding column %s.%s' % (model_table.name, model_column.name))
assert not model_column.constraints, \
'Arrrgh! I cannot automatically add columns with constraints to the database'\
'Please consider fixing me if you care!'
model_col_spec = ddl_c.get_column_specification(model_column)
sql = 'ALTER TABLE %s ADD %s' % (model_table.name, model_col_spec)
engine.execute(sql)
# It's difficult to reliably determine if the model has changed
# a column definition. E.g. the default precision of columns
# is None, which means the database decides. Therefore when I look at the model
# it may give the SQL for the column as INTEGER but when I look at the database
# I have a definite precision, therefore the returned type is INTEGER(11)
for c in to_check:
model_column = model_table.c[c]
db_column = db_table.c[c]
x = model_column == db_column
logging.debug('Checking column %s.%s' % (model_table.name, model_column.name))
model_col_spec = ddl_c.get_column_specification(model_column)
db_col_spec = ddl_c.get_column_specification(db_column)
model_col_spec = re.sub('[(][\d ,]+[)]', '', model_col_spec)
db_col_spec = re.sub('[(][\d ,]+[)]', '', db_col_spec)
db_col_spec = db_col_spec.replace('DECIMAL', 'NUMERIC')
db_col_spec = db_col_spec.replace('TINYINT', 'BOOL')
if model_col_spec != db_col_spec:
logging.warning('Column %s.%s has specification %r in the model but %r in the database' %
(model_table.name, model_column.name, model_col_spec, db_col_spec))
if model_column.constraints or db_column.constraints:
# TODO, check constraints
logging.debug('Column constraints not checked. I am too dumb')
for c in to_remove:
model_column = getattr(db_table.c, c)
logging.warning('Column %s.%s in the database is not in the model' % (model_table.name, model_column.name))
def _column_names(table):
# Autoloaded columns return unicode column names - make sure we treat all are equal
return set((unicode(i.name) for i in table.c))
+0
대단히 감사합니다! 정확히 내가 무엇을 찾고 있었는지. – kay
0
# database.py has definition for engine.
# from sqlalchemy import create_engine
# engine = create_engine('mysql://......', convert_unicode=True)
from database import engine
from sqlalchemy import DDL
add_column = DDL('ALTER TABLE USERS ADD COLUMN city VARCHAR(60) AFTER email')
engine.execute(add_column)
0
Alembic 데이터베이스의 마이그레이션을 제공하는 최신 패키지입니다.
관련 문제
- 1. 새 필드 추가 대 별도의 테이블 만들기
- 2. 이진 직렬화, 클래스에 새 필드 추가 - 작동합니까?
- 3. 큰 mysql 테이블에 새 열 추가
- 4. Magento - sales_flat_quote_item 및 sales_flat_order_item에 새 열 추가
- 5. 중첩 세트 모델 및 SQLAlchemy - 새 노드 추가
- 6. SQL Server 테이블에 새 텍스트 열 만들기 : 어떤 형식을 선택해야합니까?
- 7. 가입 테이블에 새 레코드 만들기
- 8. MySQL : 큰 테이블에 필드 추가
- 9. 데이터가있는 최대 절전 모드 테이블에 열 추가
- 10. 런타임에 새 열 추가
- 11. SQLAlchemy - 최대 열 길이
- 12. 라이브 데이터가 포함 된 테이블에 새 열 추가
- 13. trac AccountManager 플러그인에 새 열 추가
- 14. Oracle OLTP 테이블에 열 추가
- 15. 레일스 테이블에 새 행 추가
- 16. SQL Server 2008의 기존 테이블에 대한 열 순서 변경/새 열 추가
- 17. Dreamweaver for PHP 클래스에 새 "레이아웃"만들기
- 18. EF4.1 CodeFirst : 조인 테이블에 필드 추가
- 19. TurboGears2/SQLAlchemy : 자동 증가 기본 키가있는 테이블에 새 행 삽입
- 20. 새 데이터 소스로 GridView에 새 열 추가
- 21. jQuery의 tablesorter로 관리되는 테이블에 동적으로 열 추가
- 22. dbml 파일의 테이블에 수동으로 열 추가
- 23. 특정 순서로 새 테이블 열 추가
- 24. Java 라이브러리 클래스에 새 함수 추가
- 25. 기능의 SharePoint 목록 및 필드 만들기
- 26. MS Access 조인을 사용하여 새 필드 만들기
- 27. Sqlalchemy & Pylons : 이전에 정의 된 데이터베이스에 새 테이블을 추가 하시겠습니까?
- 28. 수십억 개의 행을 가진 열 데이터베이스에 새 열 추가
- 29. Datatable 새 열 및 값 추가 속도 문제
- 30. ASP.NET MVC 뷰의 테이블에 동적으로 열 추가
안녕하십니까, 많은 생각 ... – jagguli
새 링크를 요청할 수 있습니까? 그 사람은 죽은 것처럼 보입니다. 미리 감사드립니다. – Nonsingular