Flask Sqlalchemy 跨数据库操作

Flask项目中若需要连接多个数据库,可以这样操作

在配置中添加 SQLALCHEMY_BINDS,字典类型,可以添加多个

SQLALCHEMY_DATABASE_URI = 'mysql://root:root@localhost/db_one_name?charset=utf8mb4'
SQLALCHEMY_BINDS = {
        'bind_name': 'mysql://root:root@localhost/db_two_name?charset=utf8mb4',
    }

在定义Model时候关联到对应DB中

class User(db.Model):
    __tablename__ = 'user'
    __bind_key__ = 'bind_name'  # 这里为SQLALCHEMY_BINDS中其他数据库的key

    user_id = db.Column(db.Integer, primary_key=True)
    girl_friend = db.Column(db.String(64)) 

这样就可跨库访问除主数据库外的库中的数据

但此法访问不支持跨库多表关联查询,如果非用不可,我的做法是不依赖框架用engine再连接一个,然后代码拼sql实现,觉得比较low,有大神欢迎指导?

如果用alembic的话,这样关联多库会生成关联表的空表到SQLALCHEMY_DATABASE_URI主库中

解决方法是修改alembic中env.py里的代码,把忽略表生成的表名配置放在alembic.ini中

env.py里的代码修改如下

def exclude_tables_from_config(config_):
    tables_ = config_.get("tables", None)
    tables = []
    if tables_ is not None:
        tables = tables_.split(",")
    return tables


exclude_tables = exclude_tables_from_config(config.get_section('alembic:exclude'))


def include_object(object, name, type_, reflected, compare_to):
    if type_ == "table" and name in exclude_tables:
        return False
    else:
        return True


def run_migrations_offline():
    """Run migrations in 'offline' mode.

    This configures the context with just a URL
    and not an Engine, though an Engine is acceptable
    here as well.  By skipping the Engine creation
    we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the
    script output.

    """
    url = config.get_main_option("sqlalchemy.url")
    context.configure(
        url=url, target_metadata=target_metadata, literal_binds=True, include_object=include_object)

    with context.begin_transaction():
        context.run_migrations()


def run_migrations_online():
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """
    connectable = engine_from_config(
        config.get_section(config.config_ini_section),
        prefix='sqlalchemy.',
        poolclass=pool.NullPool)

    with connectable.connect() as connection:
        context.configure(
            connection=connection,
            target_metadata=target_metadata,
            include_object=include_object
        )

        with context.begin_transaction():
            context.run_migrations()


if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()

albic.ini里新增配置

[alembic:exclude]
tables = table_name_one,table_name_two

 

你可能感兴趣的:(tips)