Проблемы с MySQL, SQLAlchemy, Flask и flask.ext.script - create_all() не создает таблицы

Я не могу создавать таблицы, когда я делаю следующее в моем virtualenv:

(plasma) $ python checkup_web.py shell
> from app import db 
> db.create_all()

Нет сообщения об ошибке. Вот структура моего проекта:

root
---app
------__init__.py
------models.py
------[various blueprints]
---checkup_web.py
---config.py

Я могу включить больше кода, если это необходимо, но я считаю, что это важные файлы для рассмотрения:

1) checkup_web.py

#!/usr/bin/env python
import os
from app import create_app, db
from flask.ext.script import Manager

app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)


if __name__ == '__main__':
    manager.run()

2) config.py

import os

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY')


class DevelopmentConfig(Config):
    DEBUG = True
    SECRET_KEY = os.environ.get('SECRET_KEY') or 't0p s3cr3t'
    SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
        'mysql+pymysql://root:root_password@localhost/checkup_db'

class TestingConfig(Config):
    TESTING = True
    SECRET_KEY = 'secret'


class ProductionConfig(Config):
    pass


config = {
    'development': DevelopmentConfig,
    'testing': TestingConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig
}

3) app / __ init__.py

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from config import config

db = SQLAlchemy()

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    db.init_app(app)    

    from .families import families as families_blueprint
    app.register_blueprint(families_blueprint)

    from .patients import patients as patients_blueprint
    app.register_blueprint(patients_blueprint)

    from .doctors import doctors as doctors_blueprint
    app.register_blueprint(doctors_blueprint)

    from .conversations import conversations as conversations_blueprint
    app.register_blueprint(conversations_blueprint)

    from .appointments import appointments as appointments_blueprint
    app.register_blueprint(appointments_blueprint)

    return app

4) app / models.py (не уверен, что я здесь что-то не так делаю - впервые использую SQLAlchemy)

from datetime import datetime
from . import db

family_2_doc = db.Table('family_2_doc',
    db.Column('family_id', db.Integer, db.ForeignKey('families.id')),
    db.Column('doctor_id', db.Integer, db.ForeignKey('users.id'))
)

patient_2_doc = db.Table('patient_2_doc',
    db.Column('patient_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('doctor_id', db.Integer, db.ForeignKey('users.id'))
)

class Family(db.Model):
    __tablename__ = 'families'
    id = db.Column(db.Integer, primary_key=True)
    street_address = db.Column(db.String(64))
    city = db.Column(db.String(64))
    zipcode = db.Column(db.String(64))
    country = db.Column(db.String(64))
    phone_number = db.Column(db.String(64))
    stripe_id = db.Column(db.String(64))
    billing_valid = db.Column(db.Boolean)
    num_relationships = db.Column(db.Integer)
    doctors = db.relationship('Doctor', secondary=family_2_doc,
        backref=db.backref('families', lazy='dynamic'), lazy='dynamic')
    patients = db.relationship('Patient', backref='family', lazy='dynamic')

class Clinic(db.Model):
    __tablename__ = 'clinics'
    id = db.Column(db.Integer, primary_key=True)
    street_address = db.Column(db.String(64))
    city = db.Column(db.String(64))
    zipcode = db.Column(db.String(64))
    country = db.Column(db.String(64))
    phone_number = db.Column(db.String(64))
    doctors = db.relationship('Doctor', backref='clinic', lazy='dynamic')
    admins = db.relationship('Admin', backref='clinic', lazy='dynamic')

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)
    first_name = db.Column(db.String(64))
    last_name = db.Column(db.String(64))
    password_hash = db.Column(db.String(128))
    date_joined = db.Column(db.DateTime())
    discriminator = Column('type', String(50))
    __mapper_args__ = {'polymorphic_on': discriminator}

class Patient(User):
    __mapper_args__ = {'polymorphic_identity': 'patient'}
    dob = db.Column(db.String(64))
    relationship_to_creator = db.Column(db.Boolean) # is equal to 'creator' if patient is creator
    is_primary = db.Column(db.Boolean)
    street_address = db.Column(db.String(64))
    city = db.Column(db.String(64))
    zipcode = db.Column(db.String(64))
    country = db.Column(db.String(64))
    phone_number = db.Column(db.String(64))
    profile_pic = db.Column(db.String(64))
    doctors = db.relationship('Doctor', secondary=patient_2_doc,
        backref=db.backref('patients', lazy='dynamic'), lazy='dynamic')
    appointments = db.relationship('Appointment', backref='patient', lazy='dynamic')

class Doctor(User):
    __mapper_args__ = {'polymorphic_identity': 'doctor'}
    practice_street_address = db.Column(db.String(64))
    practice_city = db.Column(db.String(64))
    practice_zipcode = db.Column(db.String(64))
    practice_country = db.Column(db.String(64))
    practice_phone_number = db.Column(db.String(64))
    personal_street_address = db.Column(db.String(64))
    personal_city = db.Column(db.String(64))
    personal_zipcode = db.Column(db.String(64))
    personal_country = db.Column(db.String(64))
    personal_phone_number = db.Column(db.String(64))
    schedule_start = db.Column(db.DateTime())
    schedule_end = db.Column(db.DateTime())
    appointments = db.relationship('Appointment', backref='doctor', lazy='dynamic')    

class Admin(User):
    __mapper_args__ = {'polymorphic_identity': 'admin'}

class Appointment(db.Model):
    __tablename__ = 'appointments'
    is_subscriber = db.Column(db.Boolean)
    start = db.Column(db.DateTime())
    end = db.Column(db.DateTime())
    notes = db.Column(db.Text())

class Message(db.Model):
    __tablename__ = 'messages'
    body = db.Column(db.Text())
    timestamp = db.Column(db.DateTime())
    user1_id = db.Column(db.Integer) # smaller id
    user2_id = db.Column(db.Integer) # larger id
    user_sender_id = db.Column(db.Integer)
    message_number = db.Column(db.Integer)

class Conversation(db.Model):
    __tablename__ = "conversations"
    user1_id = db.Column(db.Integer) # smaller id
    user2_id = db.Column(db.Integer) # larger id
    total_messages = db.Column(db.Integer)

К сожалению, несмотря на отсутствие каких-либо ошибок, вызов create_all() не приводит ни к каким таблицам в моей базе данных mysql:

$ mysql -u root -p
Password: *********

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| channels           |
| checkup_db         |
| comments           |
| media              |
| mysql              |
| notifications      |
| performance_schema |
| reactions          |
| sessions           |
| shares             |
| sparks             |
| test               |
| users              |
+--------------------+
14 rows in set (0.01 sec)

mysql> use checkup_db
Database changed

mysql> show tables;
Empty set (0.00 sec)

Буду очень признателен за любые мысли / советы!

1 ответ

Решение

Я думаю, что проблема в том, что модели не импортируются. Когда вы делаете:

from app import db

вы запускаете создание объекта SQLAlchemy, но модели не регистрируются. Итак, тогда db.create_all() думает, что нет таблиц для создания.

Если вы импортируете модели, то они собираются зарегистрироваться в объекте базы данных. Это может показаться странным, потому что вам на самом деле не нужно использовать модели напрямую, но это единственный способ, которым объект базы данных узнает о них.

Другие вопросы по тегам