I\'m fairly new to using relational databases, so I prefer using a good ORM to simplify things. I spent time evaluating different Python ORMs and I think SQLAlchemy is what
If you are looking to create dynamic classes and tables you can use the following technique based from this tutorial URL I found here (http://sparrigan.github.io/sql/sqla/2016/01/03/dynamic-tables.html), I modified how he did it a bit.
from sqlalchemy import create_engine
engine = create_engine('sqlite:///test.db', echo=True)
from sqlalchemy import Column, Integer,Float,DateTime, String, MetaData
metadata = MetaData()
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session() # create a Session
Base = declarative_base()
First include all the needed dependencies and create your session and Base.
The key to creating it dynamically is this here:
attr_dict = {'__tablename__': 'default','id': Column(Integer, primary_key=True, auto_increment=True)}
you could create a table from just this by taking advantage of the 'type' function in python.
myClass = type('ClassnameHere', (Base,), attr_dict)
Note that we are passing in attr_dict, this will give the required tablename and column information to our class, but the difference is we are defining the class name through a string! This means you could create a loop for example going through an array of strings to start creating tables dynamically!
Next all you have to do is simply call
Base.metadata.create_all(engine)
Because the dynamic class we created inherits from Base the command will simply create the tables!
You add to this table for example like this now:
SomeRow = myClass(id='2')
session.add(SomeRow)
session.commit()
This can go even further if you you don't know the column names as well. Just refer to the article to learn how to do that.
You would essentially do something like this though:
firstColName = "Ill_decide_later"
secondColName = "Seriously_quit_bugging_me"
new_row_vals = myClass(**{firstColName: 14, secondColName: 33})
The ** operator takes the object and unpacks it so that firstColName and secondColName are added with assignment operators so it would essentially be the same thing as this:
new_row_vals = myClass(firstColName=14, secondColName=33)
The advantage of this technique is now you can dynamically add to the table without even having to define the column names!
These column names could be stored in a string array for example or whatever you wanted and you just take it from there.
maybe i didn't quite understand what you want, but this recipe create identical column in different __tablename__
class TBase(object):
"""Base class is a 'mixin'.
Guidelines for declarative mixins is at:
http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#mixin-classes
"""
id = Column(Integer, primary_key=True)
data = Column(String(50))
def __repr__(self):
return "%s(data=%r)" % (
self.__class__.__name__, self.data
)
class T1Foo(TBase, Base):
__tablename__ = 't1'
class T2Foo(TBase, Base):
__tablename__ = 't2'
engine = create_engine('sqlite:///foo.db', echo=True)
Base.metadata.create_all(engine)
sess = sessionmaker(engine)()
sess.add_all([T1Foo(data='t1'), T1Foo(data='t2'), T2Foo(data='t3'),
T1Foo(data='t4')])
print sess.query(T1Foo).all()
print sess.query(T2Foo).all()
sess.commit()
info in example sqlalchemy
It's a very old question. Anyway if you prefer ORM, it's quite easy to generate table class with type:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
Test = type('Test', (Base,), {
'__tablename__': 'test',
'test_id': Column(Integer, primary_key=True, autoincrement=True),
'fldA': Column(String),
... other columns
}
)
Base.metadata.create_all(engine)
# passed session create with sqlalchemy
session.query(Test).all()
Making a class factory, it's easy to assign names to a class and database table.
We are spoiled by SQLAlchemy.
What follows below is taken directly from the tutorial,
and is really easy to setup and get working.
And because it is done so often,
the documentation moved to full declarative in Aug 2011.
Setup your environment (I'm using the SQLite in-memory db to test):
>>> from sqlalchemy import create_engine
>>> engine = create_engine('sqlite:///:memory:', echo=True)
>>> from sqlalchemy import Table, Column, Integer, String, MetaData
>>> metadata = MetaData()
Define your table:
>>> players_table = Table('players', metadata,
... Column('id', Integer, primary_key=True),
... Column('name', String),
... Column('score', Integer)
... )
>>> metadata.create_all(engine) # create the table
If you have logging turned on, you'll see the SQL that SQLAlchemy creates for you.
Define your class:
>>> class Player(object):
... def __init__(self, name, score):
... self.name = name
... self.score = score
...
... def __repr__(self):
... return "<Player('%s','%s')>" % (self.name, self.score)
Map the class to your table:
>>> from sqlalchemy.orm import mapper
>>> mapper(Player, players_table)
<Mapper at 0x...; Player>
Create a player:
>>> a_player = Player('monty', 0)
>>> a_player.name
'monty'
>>> a_player.score
0
That's it, you now have a your player table.
you can use declarative method for dynamically creating tables in database
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
Base = declarative_base()
class Language(Base):
__tablename__ = 'languages'
id = Column(Integer, primary_key=True)
name = Column(String(20))
extension = Column(String(20))
def __init__(self, name, extension):
self.name = name
self.extension = extension
Maybe look at SQLSoup, which is layer over SQLAlchemy.
You can also create the tables using plain SQL, and to dynamically map, use these libraries if they already don't have create table function.
Or alternatively create a dynamic class and map it:
tableClass = type(str(table.fullname), (BaseTable.BaseTable,), {})
mapper(tableClass, table)
where BaseTable can be any Python class which you want all your table classes to inherit from, e.g. such Base
class may have some utility or common methods, e.g. basic CRUD methods:
class BaseTable(object): pass
Otherwise you need not pass any bases to type(...)
.