class A:
var = 'hello'
type(A.var) # returns: <class 'str'>
A.var.__class__.__name__ # returns: 'str'
vars(A) # returns: mappingproxy({'__module__': '__main__', 'var': 'hello', '__dict__': <attribute ' __dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None, '__getattribute__': <slot wrapper '__getattribute__' of 'object' objects>})
given A.var is it possible to find class A, or just var is related to class A, may be something similar to 'qualname' for methods.
Edited
reason I wanted to find the class name is I am implementing micro ORM, similar to SQLAlchemy using declarative mapping.
As you can see in this example.
import sqlalchemy as sa
import sqlalchemy.ext.declarative
meta = sa.MetaData()
DeclarativeBase = sa.ext.declarative.declarative_base(metadata=meta)
class User(DeclartiveBase):
__tablename__ = 'user'
id = sa.Column(Integer, primary_key=True)
name = sa.Column(String)
fullname = sa.Column(String)
as you can see class is used as the abstraction for the real table, intresting thing is you can still access all the column using vars(Users) and filter column using isinstance(<var>, sa.Column).
while doing query some how query is able to know which table the row is from, which is similar to the question I asked above, may its something to do with sa.Column.
Session = sa.orm.sessionmaker(bind=engine)
session = Session()
rows = session.query(
User.id,
User.name,
).all()
Sample
This is sample of the implemenation, which is able to do basic table creating, insertion and update.
class Col(str):
pass
class Base:
@classmethod
def childs(cls):
subclasses = set()
work = [cls]
while work:
parent = work.pop()
for child in parent.__subclasses__():
if child not in subclasses:
subclasses.add(child)
work.append(child)
return subclasses
@classmethod
def create(cls, cursor):
query = 'CREATE TABLE IF NOT EXISTS {} ({})'.format(
cls.__tablename__,
', '.join(
k + ' ' + v
for k, v in vars(cls).items()
if isinstance(v, Col)
)
)
cursor.execute(query)
@staticmethod
def create_all_tables(cursor):
for cls in __class__.childs():
cls.create(cursor)
@classmethod
def drop(cls, cursor):
query = 'DROP TABLE IF EXISTS {}'.format(
cls.__tablename__,
)
cursor.execute(query)
@classmethod
def insert(cls, cursor, kvRow):
query = 'INSERT INTO {} ({}) VALUES(:{})'.format(
cls.__tablename__,
', '.join(kvRow.keys()),
', :'.join(kvRow.keys())
)
cursor.execute(query, kvRow)
@classmethod
def update(cls, cursor, kvRow):
query = 'UPDATE {} SET ({})=(:{}) WHERE name=\'{}\''.format(
cls.__tablename__,
', '.join(kvRow.keys()),
', :'.join(kvRow.keys()),
kvRow['name']
)
cursor.execute(query, kvRow)
using it
class User(Base):
__tablename__ = 'user'
id = Col('INTEGER PRIMARY KEY')
name = Col('VARCHAR')
fullname = Col('VARCHAR')
now creating table is similar to sqlalchemy meta.create_all(bind=engine, checkfirst=True)
import sqlite3
conn = sqlite3.connect('./sqlite.db')
cursor = conn.cursor()
Base.create_all_tables(cursor)
Which I don't understand is how sqlchemy session.query is able to understand the table the row is from.
from is it possible to find class name given class variable
No comments:
Post a Comment