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

问题描述 投票:16回答:7

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

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

有人可以给我一些提示,以帮助我摆脱大脑僵局吗?这有可能吗?

注意:如果我要问的内容更容易实现,我愿意接受Python中的其他ORM。只要向我展示如何:-)

python database sqlalchemy
7个回答
28
投票

我们被SqlAlchemy宠坏了。以下内容直接取自tutorial,并且真的很容易设置和工作。

而且因为它经常这样做,他们使这变得更加容易用all-in-one "declarative" method

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

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

定义您的表:

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

如果打开了日志记录,您将看到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)

将类映射到您的表:

>>> from sqlalchemy.orm import mapper
>>> mapper(Player, players_table) 
<Mapper at 0x...; Player>

创建玩家:

>>> a_player = Player('monty', 0)
>>> a_player.name
'monty'
>>> a_player.score
0

就这样,您现在有了一个玩家表。另外,SqlAlchemy googlegroup很棒。


4
投票

这是一个非常老的问题。无论如何,如果您喜欢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()

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


3
投票

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

您还可以使用普通的SQL创建表,并且要动态映射,请使用这些库(如果它们还没有创建表的功能。)>

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

tableClass = type(str(table.fullname), (BaseTable.BaseTable,), {})
mapper(tableClass, table)

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

class BaseTable(object): pass

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


2
投票

您可以使用声明性方法在数据库中动态创建表


1
投票

当我尝试使用SQLAlchemy自动化简单的CRUD任务时,我遇到了同样的问题。这是简单的解释和一些代码:http://www.devx.com/dbzone/Article/42015


0
投票

也许我不太了解您想要什么,但是此食谱在不同的__tablename__中创建了相同的列


0
投票

如果您要创建动态类和表,则可以根据我在此处(http://sparrigan.github.io/sql/sqla/2016/01/03/dynamic-tables.html)找到的本教程URL,使用以下技术,我对此做了一些修改。

© www.soinside.com 2019 - 2024. All rights reserved.