我正在尝试建立多数据库连接。现在无法为多个数据库生成单个引擎连接。这是通过在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()