I am not able to create tables when I do the following in my virtualenv:
(plasma) $ python checkup_web.py shell
> from app import db
> db.create_all()
There is no error message thrown at all. Here's the structure of my project:
root
---app
------__init__.py
------models.py
------[various blueprints]
---checkup_web.py
---config.py
I can include more code if necessary, but I believe that these are the important files for consideration:
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 (not sure if I'm doing anything wrong here - first time using 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)
Unfortunately despite not throwing any errors, the call to create_all() does not produce any tables in my mysql database:
$ 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)
I'd very much appreciate any thoughts/advice!
I think the problem is that the models are not imported. When you do:
from app import db
you trigger the creation of the SQLAlchemy object, but the models are not registered. So then db.create_all()
thinks there are no tables to create.
If you import the models, then they are going to register themselves with the database object. This may seem odd, because you don't really need to use the models directly, but it is the only way the database object learns about them.