SqlAlchemy中的动态表创建和ORM映射

Jay*_*son 15 python database sqlalchemy

我对使用关系数据库相当新,所以我更喜欢使用一个好的ORM来简化事情.我花时间评估不同的Python ORM,我认为SQLAlchemy就是我需要的.但是,我已经陷入了精神上的死胡同.

我需要创建一个新表来与我在应用程序的播放器表中创建的每个玩家实例一起使用.我想我知道如何通过元数据更改表的名称然后调用create函数来创建表,但我不知道如何将它映射到新的动态类.

有人可以给我一些提示,帮助我克服大脑?这甚至可能吗?

注意:我对Python中的其他ORM开放,如果我要求的更容易实现.只是告诉我如何:-)

ber*_*nie 26

我们绝对被SqlAlchemy宠坏了.
下面的内容直接来自教程,
非常容易设置并开始工作.

而且由于经常这样做,
Mike Bayer
一体化的"声明式"方法使这变得更加容易.

设置你的环境(我正在使用SQLite内存数据库来测试):

>>> from sqlalchemy import create_engine
>>> engine = create_engine('sqlite:///:memory:', echo=True)
>>> from sqlalchemy import Table, Column, Integer, String, MetaData
>>> metadata = MetaData()
Run Code Online (Sandbox Code Playgroud)

定义你的表格:

>>> players_table = Table('players', metadata,
...   Column('id', Integer, primary_key=True),
...   Column('name', String),
...   Column('score', Integer)
... )
>>> metadata.create_all(engine) # create the table
Run Code Online (Sandbox Code Playgroud)

如果您打开了日志记录,您将看到SqlAlchemy为您创建的SQL.

定义你的课程:

>>> 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)
Run Code Online (Sandbox Code Playgroud)

将类映射到表:

>>> from sqlalchemy.orm import mapper
>>> mapper(Player, players_table) 
<Mapper at 0x...; Player>
Run Code Online (Sandbox Code Playgroud)

创建一个播放器:

>>> a_player = Player('monty', 0)
>>> a_player.name
'monty'
>>> a_player.score
0
Run Code Online (Sandbox Code Playgroud)

就是这样,你现在有一个你的玩家桌子.
此外,SqlAlchemy谷歌组很棒.
Mike Bayer很快回答问题.

  • 谢谢(你的)信息.不是我想要的.我正在尝试超越这个的东西,每个玩家另一张桌子. (3认同)

aih*_*iho 10

这是一个非常古老的问题。无论如何,如果您更喜欢 ORM,那么生成具有类型的表类非常容易:

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()
Run Code Online (Sandbox Code Playgroud)

制作类工厂,很容易为类和数据库表分配名称。


Jos*_*han 6

如果您正在寻找创建动态类和表,您可以使用以下基于我在此处找到的教程 URL 的技术(http://sparrigan.github.io/sql/sqla/2016/01/03/dynamic-tables.html ),我稍微修改了他的做法。

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()
Run Code Online (Sandbox Code Playgroud)

首先包含所有需要的依赖项并创建您的会话和 Base。

动态创建它的关键在这里:

attr_dict = {'__tablename__': 'default','id': Column(Integer, primary_key=True, auto_increment=True)}
Run Code Online (Sandbox Code Playgroud)

您可以通过利用python中的“类型”函数来创建一个表。

myClass = type('ClassnameHere', (Base,), attr_dict)

请注意,我们传入的是attr_dict,这将为我们的类提供所需的表名和列信息,但不同之处在于我们通过字符串定义类名!这意味着您可以创建一个循环,例如遍历字符串数组以开始动态创建表!

接下来你要做的就是简单地调用

Base.metadata.create_all(engine)
Run Code Online (Sandbox Code Playgroud)

因为我们创建的动态类继承自Base该命令将简单地创建表!

您现在添加到此表中,例如:

SomeRow = myClass(id='2')
session.add(SomeRow)
session.commit()
Run Code Online (Sandbox Code Playgroud)

如果您也不知道列名,这可以更进一步。只需参考文章即可了解如何执行此操作。

你基本上会做这样的事情:

firstColName = "Ill_decide_later"
secondColName = "Seriously_quit_bugging_me"

new_row_vals = myClass(**{firstColName: 14, secondColName: 33})
Run Code Online (Sandbox Code Playgroud)

** 运算符获取对象并将其解包,以便为 firstColName 和 secondColName 添加赋值运算符,因此它本质上与此相同:

new_row_vals = myClass(firstColName=14, secondColName=33)
Run Code Online (Sandbox Code Playgroud)

这种技术的优点是现在您可以动态添加到表中,甚至不必定义列名!

例如,这些列名可以存储在字符串数组中,或者您想要的任何内容中,您只需从那里获取它。


Anu*_*yal 5

也许看看SQLSoup,它是 SQLAlchemy 上的一层。

您还可以使用普通 SQL 创建表,并动态映射,如果这些库没有创建表功能,请使用这些库。

或者创建一个动态类并映射它:

tableClass = type(str(table.fullname), (BaseTable.BaseTable,), {})
mapper(tableClass, table)
Run Code Online (Sandbox Code Playgroud)

其中 BaseTable 可以是您希望所有表类都继承自的任何 Python 类,例如此类Base类可能具有一些实用程序或通用方法,例如基本的 CRUD 方法:

class BaseTable(object): pass
Run Code Online (Sandbox Code Playgroud)

否则,您无需将任何基数传递给type(...).