1

I've seen quiet a few questions similar to this posted on here, but I found nothing that helped. I'm trying to write unit tests using Flask-Testing and Flask-Fixtures. I've run into a problem since Flask-Fixtures calls create_all on the db passed to it, and in this case it isn't actually creating tables. I checked db.metadata.tables.keys which shows tables of all the models created using db.Model

config.py:

import os
from config import BASE_DIR

# SQLALCHEMY_DATABASE_URI = 'sqlite:///test-db'
SQLALCHEMY_DATABASE_URI = 'sqlite:////Users/XXX/projects/XXX-api/app/inventory/test-db'
testing = True
debug = True

FIXTURES_DIRS = (
    os.path.join(BASE_DIR, "inventory/"),
)

Table creation failing when I'm doing this:

from flask_api import FlaskAPI
from flask.ext.sqlalchemy import SQLAlchemy
from .models import db


app = FlaskAPI(__name__)
app.config.from_object('app.test_config')

ctx = app.app_context()
ctx.push()
db.init_app(app)
db.create_all()

a vars(db.metadata) gives this:

{'_bind': None,
 '_fk_memos': defaultdict(list, {}),
 '_schemas': set(),
 '_sequences': {},
 'naming_convention': immutabledict({'ix': 'ix_%(column_0_label)s'}),
 'schema': None,
 'tables': immutabledict({'gr_merchant_ftp_info': Table('gr_merchant_ftp_info', MetaData(bind=None), Column('id', BigInteger(), table=<gr_merchant_ftp_info>, primary_key=True, nullable=False), Column('merchant_id', BigInteger(), table=<gr_merchant_ftp_info>), Column('chain_id', BigInteger(), table=<gr_merchant_ftp_info>), Column('hostname', String(length=128), table=<gr_merchant_ftp_info>, nullable=False), Column('username', String(length=128), table=<gr_merchant_ftp_info>, nullable=False), Column('password', String(length=128), table=<gr_merchant_ftp_info>, nullable=False), Column('path', String(length=512), table=<gr_merchant_ftp_info>, nullable=False), Column('install_ts', DateTime(timezone=True), table=<gr_merchant_ftp_info>, server_default=DefaultClause(<sqlalchemy.sql.elements.TextClause object at 0x11007dd10>, for_update=False)), Column('parsed_file_base_path', String(length=256), table=<gr_merchant_ftp_info>), schema=None), 'gr_article_product_mapping': Table('gr_article_product_mapping', MetaData(bind=None), Column('id', BigInteger(), table=<gr_article_product_mapping>, primary_key=True, nullable=False, server_default=DefaultClause(<sqlalchemy.sql.elements.TextClause object at 0x11006fc10>, for_update=False)), Column('product_id', BigInteger(), table=<gr_article_product_mapping>), Column('article_id', String(length=128), table=<gr_article_product_mapping>), Column('install_ts', DateTime(timezone=True), table=<gr_article_product_mapping>, server_default=DefaultClause(<sqlalchemy.sql.elements.TextClause object at 0x11007d090>, for_update=False)), Column('store_code', String(length=128), table=<gr_article_product_mapping>), Column('conversion_factor', Float(precision=53), table=<gr_article_product_mapping>, server_default=DefaultClause(<sqlalchemy.sql.elements.TextClause object at 0x11007d210>, for_update=False)), schema=None), 'gr_store_merchant_mapping': Table('gr_store_merchant_mapping', MetaData(bind=None), Column('id', BigInteger(), table=<gr_store_merchant_mapping>, primary_key=True, nullable=False, server_default=DefaultClause(<sqlalchemy.sql.elements.TextClause object at 0x10f67f790>, for_update=False)), Column('merchant_id', BigInteger(), table=<gr_store_merchant_mapping>), Column('store_id', BigInteger(), table=<gr_store_merchant_mapping>), Column('install_ts', DateTime(timezone=True), table=<gr_store_merchant_mapping>, server_default=DefaultClause(<sqlalchemy.sql.elements.TextClause object at 0x11007d650>, for_update=False)), Column('store_code', String(length=128), table=<gr_store_merchant_mapping>), schema=None)})}

Any pointers will be much appreciated, thanks !

AlexLordThorsen
  • 8,057
  • 5
  • 48
  • 103
madhukar93
  • 507
  • 5
  • 23
  • Unit tests are so useful but this is the kind of shit that's a pain in the ass. I can't quite tell from your question if there's an actual stack trace, warning, or a silent failure that's happening here. I also can't tell if your ORM models work on their own but fail when you try to unit test with them. – AlexLordThorsen Feb 29 '16 at 21:53
  • it was 'failing' silently, I figured it out though. – madhukar93 Mar 01 '16 at 07:30

1 Answers1

1

I figured it out. The problem was that I was using multiple databases and I had not specified SQLALCHEMY_BINDS in my test_config. I faced a new problem afterwards though, even though create_all could create my tables now, since it goes through all binds, Flask-Fixtures apparently does not support it, it just uses the default engine, when inserting data. I worked around it by keeping SQLALCHEMY_DATABASE_URI the same as my bind, so both connected to the same database. A very crude solution but this is what I have at the moment.

madhukar93
  • 507
  • 5
  • 23