Python-Metaklasse und SQLalchemie deklarativ

Python-Metaklasse und SQLalchemie deklarativ

Metaklassen werden selten verwendet, es sei denn, sie sind Bibliotheken, aber sie werden in SQLAlchemy verwendet, daher werde ich sie nur als Referenz zusammenfassen.

Eine Metaklasse ist ein Klassentyp. Im Fall von Python ist der Typ der benutzerdefinierten Klasse im Grunde Typ.

>>> class A(object):
>>>     pass
>>>
>>> type(A)
type

Andere Metaklassen als der Typ können für spezielle Zwecke verwendet werden.

Eine vertraute Verwendung von Metaklassen findet sich in der SQL Alchemy-Deklaration.

>>> from sqlalchemy.ext.declarative import declarative_base
>>> Base = declarative_base()
>>> type(Base)
<class 'sqlalchemy.ext.declarative.api.DeclarativeMeta'>

Bei deklarativ wird die Klassendefinition automatisch der Tabellendefinition zugeordnet.

class User(Base):
    __tablename__ = 'user_account'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(Varchar(100))

Intern verwendet es eine eigene Meta-Klasse namens sqlalchemy.ext.declarative.api.DeclarativeMeta und bindet die Verarbeitung zum Zeitpunkt der Klassendefinition ein, um die Zuordnungsverarbeitung durchzuführen.

Die Definition von sqlalchemy.ext.declarative.api.DeclarativeMeta lautet wie folgt. init wird aufgerufen, wenn eine Klasse erstellt wird, die Base erbt, und die Klasse und die Tabelle darin verknüpft sind.

sqlalchemy/ext/declarative/api.py


class DeclarativeMeta(type):
    def __init__(cls, classname, bases, dict_):
        if '_decl_class_registry' not in cls.__dict__:
            _as_declarative(cls, classname, cls.__dict__)
        type.__init__(cls, classname, bases, dict_)

    def __setattr__(cls, key, value):
        _add_attribute(cls, key, value)

In Python scheint die Verwendung von Metaklasse eine relativ häufige Methode zu sein, wenn Sie automatisch etwas aus der Klassendefinition heraus tun möchten. Zum Beispiel macht die Form-Klasse von wtforms fast dasselbe.

Je nach Anwendungsfall möchten Sie diesen Vorgang möglicherweise stoppen. Betrachten wir einen Anwendungsfall wie das Zuordnen eines Tabellenobjekts, das durch Reflektion aus der Datenbank erstellt wurde, zu einer Klasse, die durch deklarative_Base erstellt wurde. In solchen Fällen kann der folgende Code verwendet werden.

from sqlalchemy import MetaData, Table
from sqlalchemy.ext.declarative import api, declarative_base
from sqlalchemy.ext.declarative.api import DeclarativeMeta


class_registry = {}
metadata = MetaData()
Base = declarative_base(class_registry=class_registry,
                        metadata=MetaData())


class MyMetaClass(DeclarativeMeta):
    def __init__(cls, classname, bases, dict_):
        #Nicht mit der Tabelle verknüpfen
        type.__init__(cls, classname, bases, dict_)

    @classmethod
    def create_class(cls, table_name, class_name, dbsession):
        tableobj = Table(table_name, metadata, autoload=True,
                         autoload_with=dbsession.bind)
        class_ = MyMetaClass(class_name, (Base), {})
        #Verknüpfen Sie explizit mit der folgenden Tabelle.
        class_.__tablename__ = tablename
        class_.__table__ = tableobj
        for c in tableobj.columns:
            setattr(class_, c.name, c)
        api.instrument_declarative(class_, class_registry, metadata)
        return class_

Recommended Posts

Python-Metaklasse und SQLalchemie deklarativ
Python3-Metaklassen-Memo
[Python] Komprimieren und dekomprimieren
Python Iterator und Generator
Python-Pakete und -Module
Vue-Cli- und Python-Integration
Ruby, Python und Map
Verwenden Sie SQL Alchemy und Multiprocessing
Python-Eingabe und Ausgabe
Metaklasse und Instanz
Python asyncio und ContextVar
Ver- und Entschlüsselung mit Python
3-3, Python-Zeichenfolge und Zeichencode
Python 2-Serie und 3-Serie (Anaconda Edition)
Python und Hardware-Verwenden von RS232C mit Python-
Python auf Ruby und wütend Ruby auf Python
Python-Einzug und String-Format
Python Real Number Division (/) und Integer Division (//)
Å (Ongustorome) und NFC @ Python
Lernen Sie Python-Pakete und -Module kennen
[Python] Wie man mit Klassenvariablen mit Dekorator und Metaklasse spielt
# 2 [python3] Trennung und Kommentar aus
Flache Python-Kopie und tiefe Kopie
Herstellen einer Verbindung zu verschiedenen DBs über Python (PEP 249) und SQL Alchemy
Python und Ruby Slice Memo
Python-Installation und grundlegende Grammatik
Ich habe Java und Python verglichen!
Flache Python-Kopie und tiefe Kopie
[Python] Memorandum zur Vermeidung von SQLAlchemy-Fehlern
Über Python, len () und randint ()
Informationen zu Python-Datums- und Zeitzone
Installieren Sie Python 3.7 und Django 3.0 (CentOS)
Python-Umgebungskonstruktion und TensorFlow
Python-Klassen- und Instanzvariablen
Ruby- und Python-Syntax ~ branch ~
[Python] Python und Sicherheit - is Was ist Python?
Stapel und Warteschlange in Python
Implementierung von Fibonacci und Primzahlen (Python)
Python-Grundlagen: Bedingungen und Iterationen
Python-Bitoperator und logische Summe
Python-Debug- und Testmodul
Python-Liste und Tapples und Kommas
Python-Variablen und Objekt-IDs
Python-Listeneinschlussnotation und Generator
Über Python und reguläre Ausdrücke
Group_by mit sqlalchemy und sum
Python mit Pyenv und Venv
So schreiben Sie eine Meta-Klasse, die sowohl Python2 als auch Python3 unterstützt
Unittest und CI in Python
Maxout Beschreibung und Implementierung (Python)
[Python] Quotient und Überschuss erhalten
Python 3 Sortier- und Vergleichsfunktionen
[Python] Suche nach Tiefenpriorität und Suche nach Breitenpriorität
Identität und Äquivalenz: ist und == in Python
Quellinstallation und Installation von Python
Python oder und und Operatorfalle
Fordern Sie Python3 und Selenium Webdriver heraus
Informationen zu Python- und Betriebssystemoperationen
Funktionen höherer Ordnung und Einschlussnotation in Python