Проблемы с 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()
думает, что нет таблиц для создания.
Если вы импортируете модели, то они собираются зарегистрироваться в объекте базы данных. Это может показаться странным, потому что вам на самом деле не нужно использовать модели напрямую, но это единственный способ, которым объект базы данных узнает о них.