17

run.py

if __name__ == '__main__':
    config() 
    app.run()

main.py

import database

app = Flask(__name__)

def config():
    app.config.from_object('config.DevConfig')

    # Run SQLAlchemy _that uses app.config_ and add entities if in DEBUG mode
    database.init_db(app)

    import blueprints.auth
    app.register_blueprint(blueprints.auth.auth)

database.py

db = None

def init_db(app):
    global db
    db = SQLAlchemy(app)

    from models import User, Interest, Event

    if app.config['DEBUG']:
        print 'Recreating all db'
        db.create_all() # I DO create everything
        print 'Loading test data'
        ... (here I add some Users and etc. and everything works fine - tests pass)

models.py

from database import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)
...

blueprints/auth.py

from models import User

auth = Blueprint('auth', __name__)

@auth.route('/')
def index():
    return str(User.query.get(1).interests)

And so I get

OperationalError: (OperationalError) no such table: user u'SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email, user.passhash AS user_passhash, user.vk_page AS user_vk_page \nFROM user \nWHERE user.id = ?' (1,)

What am I doing wrong?

2
  • 2
    Did the table user actually end up being created in the database? Have you checked with another program? Commented Feb 13, 2014 at 22:33
  • 2
    db.create_all() is only executed in debug mode. Is that intentional? Commented Feb 14, 2014 at 13:53

3 Answers 3

26

For anyone trying to use an in memory database:

from sqlalchemy import create_engine
from sqlalchemy.pool import StaticPool

engine = create_engine(
    "sqlite://", 
    connect_args={"check_same_thread": False}, 
    poolclass=StaticPool
)
Sign up to request clarification or add additional context in comments.

4 Comments

You're the man. This is I think the actual answer for having an in memory DB, instead of just switching to a file.
Oh my god, you're the guy. poolclass=StaticPool made the difference for me. Thanks.
I know this is old, still would you please update your answer to explain the poolclass argument, or point to the doc? Thanks in adv.
Wonderful solution. Clarification: check_same_thread=false - a connection may be accessed in multiple threads, no ProgrammingError raised StaticPool: A pool of exactly one connection, used for all request As for the documentation: sqlite3 - check_same_thread: docs.python.org/3/library/sqlite3.html sqlalchemy - poolclass - docs.sqlalchemy.org/en/20/core/…
16

There were few things I had to change to make everything work.

  1. replace DATABASE_URI with SQLALCHEMY_DATABASE_URI parametr in config
  2. replace :memory: sqlite address with /tmp/test.db

Now it works fine.

5 Comments

+1000 ... geez, that was frustrating. db.create_all() is $@#&*^#* with in-memory sqlite ... ok ...
Explanation for this behavior: gehrcke.de/2015/05/…
I understand how to complete the first part of the this answer, but I'm not sure what you mean by the second part. I assume the :memory: address needs set equal to SQLALCHEMY_DATABASE_URI, but I am not sure how to do that. What do I need to append to my config.py file?
@sudosensei it just means, don't use in-memory storage :) if you used :memory:before, don't. If you did not, you are good.
My issue was actually something different altogether. Thank you for the quick reply though!
0

To use an in-memory SQLite database without changing the create_engine parameters, use the following connection string in a URI format:

sqlite:///file::memory:?cache=shared&uri=true

Example:

from sqlalchemy import create_engine

engine = create_engine(
    "sqlite:///file::memory:?cache=shared&uri=true",
    echo=True,
    future=True
)

Notes:

See what SQLite documentation has to say about in-memory databases and shared cache. In short, in order for the same in-memory database to be accessible across multiple connections within the same process, the connection string must use the file: URI syntax - a simple :memory: connection string won't work, even if we make it :memory:?cache=shared.

Additionally, SQLAlchemy wants us to append uri=true in the end of such URI connection strings.

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.