22

増大するデータベース テーブルを処理するために、テーブル名をシャーディングしています。したがって、次のような名前のデータベース テーブルを作成できます。

table_md5one
table_md5two
table_md5three

すべてのテーブルのスキーマはまったく同じです。

SQLAlchemy を使用して、これに対応するクラスのテーブル名を動的に指定するにはどうすればよいでしょうか? declarative_base() クラスにはtablenameを事前に指定する必要があるようです。

最終的にはテーブルが多すぎて、親/基本クラスから派生したクラスを手動で指定できなくなります。テーブル名を動的に設定できるクラスを構築できるようにしたいと考えています (関数にパラメーターとして渡される可能性があります)。

4

6 に答える 6

18

OK、宣言型ではなく、カスタム SQLAlchemy 宣言を使用しました。

したがって、次のような動的テーブル オブジェクトを作成します。

from sqlalchemy import MetaData, Table, Column

def get_table_object(self, md5hash):
    metadata = MetaData()
    table_name = 'table_' + md5hash
    table_object = Table(table_name, metadata,
        Column('Column1', DATE, nullable=False),
        Column('Column2', DATE, nullable=False)
    )
    clear_mappers()
    mapper(ActualTableObject, table_object)
    return ActualTableObject

ActualTableObject は、テーブルへのクラス マッピングです。

于 2013-10-03T20:20:33.607 に答える
4

これを試して

import zlib

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, BigInteger, DateTime, String

from datetime import datetime

BASE = declarative_base()
ENTITY_CLASS_DICT = {}


class AbsShardingClass(BASE):

    __abstract__ = True

def get_class_name_and_table_name(hashid):
    return 'ShardingClass%s' % hashid, 'sharding_class_%s' % hashid

def get_sharding_entity_class(hashid):
    """
    @param hashid: hashid
    @type hashid: int
    @rtype AbsClientUserAuth
    """

    if hashid not in ENTITY_CLASS_DICT:
        class_name, table_name = get_class_name_and_table_name(hashid)
        cls = type(class_name, (AbsShardingClass,),
                   {'__tablename__': table_name})
        ENTITY_CLASS_DICT[hashid] = cls

    return ENTITY_CLASS_DICT[hashid]

cls = get_sharding_entity_class(1)
print session.query(cls).get(100)
于 2014-06-06T04:42:48.947 に答える
0

Table オブジェクトを作成する命令を使用する代わりに、通常の declarative_base を使用してクロージャを作成し、テーブル名を次のように設定できます。

def make_class(Base, table_name):
    class User(Base):
        __tablename__ = table_name
        id = Column(Integer, primary_key=True)
        name= Column(String)

    return User

Base = declarative_base()
engine = make_engine()
custom_named_usertable = make_class(Base, 'custom_name')
Base.metadata.create_all(engine)

session = make_session(engine)
new_user = custom_named_usertable(name='Adam')
session.add(new_user)
session.commit()
session.close()
engine.dispose()
于 2020-03-12T12:49:09.710 に答える