Как конвертировать SqlServer ON [PRIMARY] в модель Sqlalchemy? - PullRequest
0 голосов
/ 23 мая 2018

У меня есть запрос в sqlserver, и я хотел написать модель, соответствующую ему, используя sqlalchemy orm.Мне нужно знать, как конвертировать ON [PRIMARY] в sqlalchemy.

Вот мой запрос:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[UserModel](
[userid] [nvarchar](255) NULL,
[username] [nvarchar](255) NULL,
[serialnumber] [nvarchar](255) NULL
) ON [PRIMARY]

GO

Вот моя модель:

class UserModel(db.Model):
    __tablename__ = 'UserModel'

    userid = Column('userid', Unicode(255))
    username = Column('username', Unicode(255))
    serialnumber = Column('serialnumber', Unicode(255))

Любые предложенияКак мне этого добиться В настоящее время я получаю следующую ошибку, как показано ниже:

sqlalchemy.exc.ArgumentError: Mapper Mapper|UserModel|UserModel could not assemble any primary key columns for mapped table 'UserModel'

Я знаю, что в моей модели не определен первичный первичный ключ, но приведенный выше запрос работает нормально.Поэтому я хотел перевести вышеуказанный запрос, используя sqlalchemy orm.

1 Ответ

0 голосов
/ 24 мая 2018

Вы не можете перевести вышеупомянутый DDL, используя большинство ORM, по крайней мере напрямую, потому что они ожидают, что объекты Python соответствуют уникально идентифицируемым строкам в базе данных.Теперь, если вы точно знаете, что, например, UserModel.userid уникально идентифицирует строки, вы можете указать SQLAlchemy использовать его в качестве «первичного ключа»:

class UserModel(db.Model):
    __tablename__ = 'UserModel'

    userid = Column('userid', Unicode(255))
    username = Column('username', Unicode(255))
    serialnumber = Column('serialnumber', Unicode(255))

    __mapper_args__ = {
        'primary_key': [userid]
    }

Имейте в виду, что вы солгалиORM и любые последствия для вас.

Что касается определения файловой группы, в которой должна храниться таблица с использованием ON [PRIMARY], вам придется увеличить диалект mssql немного:

from sqlalchemy import Table
from sqlalchemy.schema import CreateTable
from sqlalchemy.ext.compiler import compiles

# Add our custom dialect specific argument
Table.argument_for('mssql', 'on', None)

@compiles(CreateTable, 'mssql')
def compile_create_table(create, compiler, **kw):
    stmt = compiler.visit_create_table(create, **kw)
    filegroup = create.element.kwargs.get('mssql_on')

    if filegroup:
        stmt = stmt.rstrip()  # Prettier output, remove newlines
        filegroup = compiler.preparer.quote(filegroup)
        stmt = f"{stmt} ON {filegroup}\n\n"

    return stmt

и добавьте необходимые аргументы таблицы в определение модели:

class UserModel(db.Model):
    ...
    __table_args__ = {
        'mssql_on': 'PRIMARY'
    }

Вы можете проверить, что полученный DDL соответствует желаемому:

In [4]: print(CreateTable(UserModel.__table__).compile(dialect=engine.dialect))

CREATE TABLE [UserModel] (
        userid NVARCHAR(255) NULL, 
        username NVARCHAR(255) NULL, 
        serialnumber NVARCHAR(255) NULL
) ON [PRIMARY]

Обратите внимание, что по крайней мере в соответствии с этот первичный Q / A является значением по умолчанию, и поэтому ON [PRIMARY] может быть просто опущен.

...