When connecting to multiple databases, do I need multiple SQLAlchemy Metadata, Base, or Session objects?

青春壹個敷衍的年華 提交于 2021-02-08 07:33:30

问题


I'm writing a SQLAlchemy app that needs to connect to a PostgreSQL database and a MySQL database. Basically I'm loading the data from an existing MySQL database, doing some transforms on it, and then saving it in PostgreSQL.

I am managing the PostgreSQL schema using SQLAlchemy's declarative base. The MySQL database already exists, and I am accessing the schema via SQLAlchemy's reflection. Both have very different schemas.

I know I need dedicated engines for each database, but I'm unclear on whether I need dedicated objects of any of the following:

  1. Base - I think this corresponds to the database schema. Since both databases have very different schemas, I will need a dedicated Base for each schema.

  2. Metadata - Is this intended to be a single global metadata object that holds all schemas from all engines?

  3. Sessions - I'm not sure, but I think I need separate sessions for each database? Or can a single session share multiple engine/Base combos? I'm using scoped_sessions.

Part of my confusion comes from not understanding the difference between Base and Metadata. The SQLAlchemy docs say:

MetaData is a container object that keeps together many different features of a database (or multiple databases) being described.

This seems to imply that a single metadata can hold multiple Base's, but I'm still a bit fuzzy on how that works. For example, I want to be able to call metadata.create_all() and create tables in PostgreSQL, but not MySQL.


回答1:


The short answer is that it's easiest to have separate instances of them all for both databases. It is possible to create a single routing session, but it has its caveats.

The sessionmaker and Session also support passing multiple binds as an argument and 2-phase commits, which can also allow using a single session with multiple databases. As luck would have it, the 2 databases that support 2-phase commits are PostgreSQL and MySQL.

About the relation between Base and metadata:

Base is a base class that has a metaclass used to declaratively create Table objects from information provided in the class itself and its subclasses. All Table objects implicitly declared by subclasses of Base will share the same MetaData.

You can provide metadata as an argument when creating a new declarative base and thus share it between multiple Bases, but in your case it is not useful.

MetaData is a collection of Table objects and their associated schema constructs. It also can hold a binding to an Engine or Session.

In short, you can have Tables and MetaData without a Base, but a Base requires MetaData to function.



来源:https://stackoverflow.com/questions/36342716/when-connecting-to-multiple-databases-do-i-need-multiple-sqlalchemy-metadata-b

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!