lundi 26 septembre 2016

When using reflect, multiple database, same tablename, only get from first database

My Program Flow

  1. get Flask app
  2. reflect sqlalchemy
  3. get restfulapi
  4. restfulapi get database with reflected sqlalchemy

Error : db.model class reflects only one database's table.

For example, when db 'nova' has table 'services' and db 'cinder' has table 'services', too.

following two classes get same table 'services' on db 'nova'.

class Service_Nova(db.model):
    __bind_key__ = 'nova'
    __tablename__ = 'services'
class Service_Cinder(db.model):
    __bind_key__ = 'cinder'
    __tablename__ = 'services'

It seems __bind_key__ can't work properly

Here's partion of my code.

my_program/__init__.py

from flask import Flask

def create_app(*args, **kwargs):
    # flask app
    app = Flask(__name__)
    app.config.from_object('setting.%s' % kwargs['env'])

    # flask_sqlalchemy, just play with api
    from my_program.database import db
    db.init_app(app)
    with app.app_context():
        db.reflect()

    # flask_restful, import requiring db.reflect()
    from my_program.restfulapi import api
    api.init_app(app)
    return app

setting/dev.py

# flask setting
SERVER_NAME = 'localhost:8943'
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_DATABASE_URI = 'mysql://nova:<nova-password>@db0.stack/nova'
SQLALCHEMY_BINDS = {
        'cinder': 'mysql://cinder:<cinder-password>@db0.stack/cinder',
        'keystone': 'mysql://keystone:<keystone-password>@db0.stack/keystone',
        'glance': 'mysql://glance:<glance-password>@db0.stack/glance',
        'nova': 'mysql://nova:<nova-password>@db0.stack/nova',
}

my_program/database.py

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

my_program/restfulapi.py

from flask_restful import Api
from apis.test import *
from apis.admin import *
from apis.project.compute import *

api = Api()

api.add_resource(HelloWorld, '/helloworld', '/')
api.add_resource(Overview_instances, '/project/compute/overview')
api.add_resource(Overview, '/admin/overview')
api.add_resource(Hypervisor, '/admin/hypervisor')
api.add_resource(Hypervisor_Host_Instances, '/admin/hypervisor/host_instances')
api.add_resource(Hostset, '/admin/hostset')
api.add_resource(Instance, '/admin/instance')
api.add_resource(Volume, '/admin/volumes')
api.add_resource(Volume_Type, '/admin/volume_type')
api.add_resource(Volume_Snapshot, '/admin/volume_snapshot')
api.add_resource(Flavor, '/admin/flavor')
api.add_resource(Image, '/admin/images')
api.add_resource(Info_Nova_Service, '/admin/info_nova_service')
api.add_resource(Info_Cinder_Service, '/admin/info_cinder_service')

*my_program/apis/test.py

from flask_restful import Resource, reqparse
from flask import jsonify
from my_program.models.keystone import Region

class HelloWorld(Resource):
    def get(self):
        # parsing request
        parser = reqparse.RequestParser()
        parser.add_argument('sample', type=str)
        parser.add_argument('data', type=str)
        args = parser.parse_args()

        return jsonify({'hello': 'world', 'data': args.data})

my_program/models/keystone.py

# same structure
# my_program/models/nova.py
# my_program/models/glance.py
# my_program/models/cinder.py

from my_program.database import db

class Region(db.Model):
    __bind_key__ = 'keystone'
    __tablename__ = 'region'

class Project(db.Model):
    __bind_key__ = 'keystone'
    __tablename__ = 'project'





Aucun commentaire:

Enregistrer un commentaire