如何使用Alembic --autogenerate迁移SQL Alchemy模型中未硬编码的多个 Postgres模式?(镜像问题的SQLAlchemy支持Postgres架构,但对于Alembic).
特别是,我们使用Postgres模式来分离共享同一组表的不同客户端.此外,客户端之间存在共享内容的模式.SQL Alchemy模型不了解模式,模式是在运行时使用设置的session.execute("SET search_path TO client1,shared").
默认情况下--autogenerate根本没有帮助,因为它检测到模型中不存在的多个模式,最终删除模式并重新创建默认模式中的每个表.
我真的想使用--autogenerate正确的管道来正确设置模式.关于Alembic的API是否/如何做到这一点的任何建议?
我有一个使用Pyramid/SQLAlchemy/Postgresql构建的Web应用程序,允许用户管理一些数据,并且该数据几乎完全独立于不同的用户.说,Alice访问alice.domain.com并且能够上传图片和文档,并且Bob访问bob.domain.com并且还能够上传图片和文档.Alice永远不会看到Bob创建的任何内容,反之亦然(这是一个简化的例子,真的可能在多个表中有很多数据,但想法是一样的).
现在,在DB后端组织数据最直接的选择是使用单个数据库,其中每个表(pictures和documents)都有user_id字段,所以,基本上,要获取所有Alice的图片,我可以做类似的事情
user_id = _figure_out_user_id_from_domain_name(request)
pictures = session.query(Picture).filter(Picture.user_id==user_id).all()
Run Code Online (Sandbox Code Playgroud)
这一切都很简单,但也存在一些缺点
所以我认为以某种方式分割每个用户的数据真的很好.我可以想到两种方法:
在同一个数据库中为Alice和Bob的图片和文档设置单独的表(Postgres的Schemas似乎是在这种情况下使用的正确方法):
documents_alice
documents_bob
pictures_alice
pictures_bob
Run Code Online (Sandbox Code Playgroud)
然后,使用一些黑魔法,根据当前请求的域"将"所有查询"路由"到一个或另一个表:
_use_dark_magic_to_configure_sqlalchemy('alice.domain.com')
pictures = session.query(Picture).all() # selects all Alice's pictures from "pictures_alice" table
...
_use_dark_magic_to_configure_sqlalchemy('bob.domain.com')
pictures = session.query(Picture).all() # selects all Bob's pictures from "pictures_bob" table
Run Code Online (Sandbox Code Playgroud)为每个用户使用单独的数据库:
- database_alice
- pictures
- documents
- database_bob
- pictures
- documents
Run Code Online (Sandbox Code Playgroud)
这似乎是最干净的解决方案,但我不确定多个数据库连接是否需要更多的RAM和其他资源,限制了可能的"租户"数量.
所以,问题是,这一切都有意义吗?如果是,我如何配置SQLAlchemy以在每个HTTP请求上动态修改表名(对于选项1)或者维护到不同数据库的连接池并为每个请求使用正确的连接(对于选项2)?
我正在使用SQL Alchemy并且有一些特定于帐户的模式.模式的名称是使用帐户ID派生的,因此在我访问应用程序服务或存储库层之前,我没有模式的名称.我想知道是否可以针对在运行时动态设置其架构的实体运行查询?
我知道我需要设置__table_args__['schema']并尝试使用内置的type(),但我总是得到以下错误:
could not assemble any primary key columns for mapped table
Run Code Online (Sandbox Code Playgroud)
我已经准备好放弃直接编写sql,但我真的很讨厌这样做.知道如何做到这一点?我正在使用SA 0.99而且我确实有PK映射.
谢谢
我正在尝试在创建的表中插入一些数据。我有一个看起来像这样的数据框:
我创建了一个表:
create table online.ds_attribution_probabilities
(
attribution_type text,
channel text,
date date ,
value float
)
Run Code Online (Sandbox Code Playgroud)
我正在运行此python脚本:
engine = create_engine("postgresql://@e.eu-central-1.redshift.amazonaws.com:5439/mdhclient_encoding=utf8")
connection = engine.raw_connection()
result.to_sql('online.ds_attribution_probabilities', con=engine, index = False, if_exists = 'append')
Run Code Online (Sandbox Code Playgroud)
我没有收到任何错误,但是当我检查表中没有数据时。有什么事吗 我是否必须承诺或执行其他步骤?
我的 app.py 文件
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres:////tmp/test.db'
db = SQLAlchemy(app) # refer https://flask-sqlalchemy.palletsprojects.com/en/2.x/api/#flask_sqlalchemy.SQLAlchemy
Run Code Online (Sandbox Code Playgroud)
我的模型类之一,我在其中导入db
from app import db
Base = declarative_base()
# User class
class User(db.Model, Base):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return '<User %r>' % self.username
def get_user_by_id(self, id):
return self.query.get(id)
Run Code Online (Sandbox Code Playgroud)
我的数据库在不同模式(多租户)中具有相同的表集,并且我需要根据特定租户即时发起的请求before_request(从子域 URL 获取租户 ID)来选择模式。
我发现 Postgres …