使用SqlAlchemy Core的多个数据库实例连接

时间:2019-02-04 18:57:35

标签: python sqlalchemy

我正在尝试建立多数据库连接。现在无法为多个数据库生成单个引擎连接。这是通过在mainschema.py(别名dbm)中定义我的主数据库(共享数据库)来实现的:

#ifdef __GNUC__
# define MYLIB_NOINLINE __attribute__((noinline))
#elif defined _MSC_VER
# define MYLIB_NOINLINE __declspec(noinline)
#else
# error Unknown compiler
#endif

然后对于每个客户端,我将在dbschema.py(别名dbc)中定义一个特定的数据库

mymetadata = MetaData()

Base = declarative_base(metadata=mymetadata)

class newbase(DeferredReflection, Base):
    __abstract__ = True

table_args = {
        'mysql_engine': dict_constants['sql_mainDB_engine'],
        'mysql_charset': dict_constants['sql_mainDB_collation'],
        'schema' : 'smv',
    }

class Company(newbase):
__tablename__ = 'companies'
__table_args__ = table_args

id = Column(INTEGER(unsigned=True), primary_key=True)
company = Column(String(255))
db = Column(String(255))
enabled = Column(BOOLEAN, nullable=False)

之后,我创建引擎:

mymetadata = MetaData()

Base = declarative_base()

table_args = {
        'mysql_engine': dict_constants['sql_mainDB_engine']
    }


# __abstract__ causes declarative to skip the production of a table or mapper for the class entirely
class newbase(DeferredReflection, Base):
    __abstract__ = True


#Creating Base Classes

class ObjectGroup(newbase):
    __tablename__ = 'objectgroups'
    __table_args__ = table_args

    id = Column(INTEGER(unsigned=True), primary_key=True, autoincrement=True)
    name = Column(String(30), unique=True, nullable=False)
    parentobjectgroup_id = Column(INTEGER(unsigned=True), ForeignKey(id,onupdate="CASCADE", ondelete="RESTRICT"), nullable=False)
    created_at = Column(DATETIME, nullable=False)
    updated_at = Column(DATETIME, nullable=False)
    enabled = Column(BOOLEAN, nullable=False)

查询示例:

self.clientconnection   = '%s://%s:%s@%s:%s/%s?charset=%s&use_unicode=0' % (self.dict_constants['sql_clientDB_driver'],
                                                                  self.dict_constants['sql_clientDB_user'], self.dict_constants['sql_clientDB_passwd'],
                                                                  host, port, db, self.dict_constants['sql_mainDB_collation'])
self.engine = create_engine(self.clientconnection, echo=False, pool_size=1, pool_timeout=30)

self.base = dbc.newbase

#opening several threads on the same time produces error in prepare, only one at a time

with sema_clientengine:
        try:
            self.base.prepare(self.engine)

这是我的阅读方式:

position_table = dbc.Position.__table__
position = alias(position_table, name='position', flat=True)
filter = and_(position.c.object_id == objectid, position.c.validpos == 1)
query = select([position]).where(filter).order_by(position.c.moment_id.desc()).limit(1)

好吧,基本上,在同一实例中,我有一个名为“ smv”的主数据库,对于每个客户端,都有一个独立的数据库。

因此,当我创建引擎并根据类运行连接时,它将转到已定义的架构。这很棒,我什至可以在数据库之间建立联接。现在,我需要将主数据库'smv'放置在不同的数据库实例上,这样我就可以进行扩展,这是因为共享引擎仅连接到客户端实例而现在smv模式不存在时一切停止的情况。

有什么想法吗?

添加于2019-02-05:

好的,经过一些测试,我可以使其与会话一起使用,请注意,Company表不仅位于与Objects不同的数据库中,而且位于不同的数据库实例,不同的IP和端口上:

    with sema_reads:
        debug_starttime = time()
        try:
            self.engine.dispose()
            with self.engine.connect() as connection:
                proxyobject = connection.execute(query)

所以这行得通,但是我需要运行更复杂的查询,对于我来说,这种方式更好,但只有在指定引擎时它才行。会话是否可以根据表类自动检测到它?还可以对来自不同数据库实例的表进行联接吗?

config_1 = {
    "sqlalchemy.url": "%s://%s:%s@%s:%s/%s" % (dict_constants['sql_mainDB_driver'], dict_constants['sql_mainDB_user'],
                                                     dict_constants['sql_mainDB_passwd'], dict_constants['sql_mainDB_host'],
                                                     dict_constants['sql_mainDB_port'], dict_constants['sql_mainDB_name']),
    "sqlalchemy.echo": False,
}

config_2 = {
    "sqlalchemy.url": "%s://%s:%s@%s:3307/clientdb" % (dict_constants['sql_mainDB_driver'], dict_constants['sql_mainDB_user'],
                                                     dict_constants['sql_mainDB_passwd'], dict_constants['sql_mainDB_host']),
    "sqlalchemy.echo": False,
}

engine_1 = engine_from_config(config_1)
engine_2 = engine_from_config(config_2)

Base = declarative_base()
Base2 = declarative_base()

class Company(Base):
    __tablename__ = 'companies'


    id = Column(INTEGER(unsigned=True), primary_key=True)
    company = Column(String(255))
    db = Column(String(255))
    enabled = Column(BOOLEAN, nullable=False)

class Object(Base2):
    __tablename__ = 'objects'

    id = Column(INTEGER(unsigned=True), primary_key=True)
    name = Column(String(30), unique=True, nullable=False)
    objectgroup_id = Column(INTEGER(unsigned=True), nullable=False)
    objectaction_id = Column(SMALLINT(unsigned=True), nullable=False)
    created_at = Column(DATETIME, nullable=False)
    updated_at = Column(DATETIME, nullable=False)
    enabled = Column(BOOLEAN, nullable=False)


#session.configure(bind={Company:engine_1})

binds = {Base:engine_1, Base2:engine_2}

session = sessionmaker(binds=binds)
session = session()

print session.query(Company).all()

print session.query(Object).all()

0 个答案:

没有答案