Skip to content

Instantly share code, notes, and snippets.

@diegoquintanav
Last active March 16, 2018 20:31
Show Gist options
  • Save diegoquintanav/76c63a6f16b982005f4a1f63e892c1d9 to your computer and use it in GitHub Desktop.
Save diegoquintanav/76c63a6f16b982005f4a1f63e892c1d9 to your computer and use it in GitHub Desktop.
SQLAlchemy gotchas (and headaches) I've dealt with

Define local model class from remote table

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/database1.db'
app.config['SQLALCHEMY_BINDS'] = {'remote': 'sqlite:////tmp/database1.db'}


db = SQLAlchemy(app)

class MyRemoteTable(db.Model):
    __table__ = Table('sles', db.Model.metadata, autoload=True)

Use two databases with Flask-SQLAlchemy, when there is a name collision between tables

class MyTable(db.Model):
    __tablename__ = 'mytable'

class MyRemoteTable(db.Model):
    __bind_key__ = 'remote'
    __tablename__ = 'mytable' # produces a name collision

Solution

Use two different declarative_base instances

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/database1.db'
app.config['SQLALCHEMY_BINDS'] = {'remote': 'sqlite:////tmp/database1.db'}

db1 = SQLAlchemy(app)

class MyTable(db1.Model):
    __tablename__ = 'mytable'

db2 = SQLAlchemy(app)

class MyRemoteTable(db2.Model):
    __bind_key__ = 'remote'
    __tablename__ = 'mytable'

Alternative solution

Instantiate the new declarative_base from the current Base. I have not tried this one

app = Flask(__name__)
db = SQLAlchemy(app)
db.NewModel = db.make_declarative_base()

class MyTable(db.Model):
    __tablename__ = 'mytable'

class MyRemoteTable(db.NewModel):
    __tablename__ = 'mytable'

About

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment