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 !

2
  • 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. Commented Feb 29, 2016 at 21:53
  • it was 'failing' silently, I figured it out though. Commented Mar 1, 2016 at 7:30

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.