Re: [sqlalchemy] Custom type compilers interplace with with_variant

2018-11-06 Thread Mike Bayer
On Tue, Nov 6, 2018 at 6:11 PM 'Van Klaveren, Brian N.' via sqlalchemy
 wrote:
>
> Hi,
>
> I want to create a custom type for TINYINT and DOUBLE.
>
> I've defined them as custom types.
>
> I want to use with_variant for them, so that in sqlite they print out as 
> TINYINT and DOUBLE.
>
> But I also want them to use the variants defined for other databases, like 
> Oracle and Postgres.
>
> The first part works fine, the second part, not so much.
>
> What's really the best way to do this?
>
> Code is attached below.
>
> Brian
>
>
> from sqlalchemy.ext.compiler import compiles
> from sqlalchemy import SmallInteger, Float
> from sqlalchemy import types
> from sqlalchemy.dialects import mysql, oracle, postgresql
> from sqlalchemy import create_engine, MetaData, Column, Boolean
> from sqlalchemy.schema import Table
>
> MYSQL = "mysql"
> ORACLE = "oracle"
> POSTGRES = "postgresql"
> SQLITE = "sqlite"
>
> class TINYINT(SmallInteger):
> """The non-standard TINYINT type."""
> __visit_name__ = 'TINYINT'
>
>
> class DOUBLE(Float):
> """The non-standard DOUBLE type."""
> __visit_name__ = 'DOUBLE'
>
> @compiles(TINYINT)
> def compile_tinyint(type_, compiler, **kw):
> return "TINYINT"
>
>
> @compiles(DOUBLE)
> def compile_double(type_, compiler, **kw):
> return "DOUBLE"
>
> byte_map = {
> MYSQL: mysql.TINYINT(),
> ORACLE: oracle.NUMBER(3),
> POSTGRES: postgresql.SMALLINT(),
> }
>
> double_map = {
> MYSQL: mysql.DOUBLE(),
> ORACLE: oracle.BINARY_DOUBLE(),
> POSTGRES: postgresql.DOUBLE_PRECISION(),
> }
>
> def byte(**kwargs):
> return _vary(TINYINT(), byte_map, kwargs)
>
>
> def double(**kwargs):
> return _vary(DOUBLE(), double_map, kwargs)
>
> def _vary(type, variant_map, overrides):
> for dialect, variant in overrides.items():
> variant_map[dialect] = variant
> for dialect, variant in variant_map.items():
> type.with_variant(variant, dialect)

I think you need to reassign to type there, "type = type.with_variant(...)"

> return type
>
>
> metadata = MetaData()
>
> t = Table("MyTable", metadata,
>   Column("my_byte", byte()),
>   Column("my_double", double())
>   )
>
>
> def metadata_dump(sql, *multiparams, **params):
> # print or write to log or file etc
> print(sql.compile(dialect=engine.dialect))
>
> engine = create_engine("sqlite://", strategy='mock', executor=metadata_dump)
> metadata.create_all(engine)
>
>
> def metadata_dump(sql, *multiparams, **params):
> # print or write to log or file etc
> print(sql.compile(dialect=engine.dialect))
>
> engine = create_engine("oracle://", strategy='mock', executor=metadata_dump)
> metadata.create_all(engine)
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example.  See  http://stackoverflow.com/help/mcve for a full 
> description.
> ---
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Custom type compilers interplace with with_variant

2018-11-06 Thread 'Van Klaveren, Brian N.' via sqlalchemy
Hi,

I want to create a custom type for TINYINT and DOUBLE.

I've defined them as custom types. 

I want to use with_variant for them, so that in sqlite they print out as 
TINYINT and DOUBLE. 

But I also want them to use the variants defined for other databases, like 
Oracle and Postgres.

The first part works fine, the second part, not so much.

What's really the best way to do this?

Code is attached below.

Brian


from sqlalchemy.ext.compiler import compiles
from sqlalchemy import SmallInteger, Float
from sqlalchemy import types
from sqlalchemy.dialects import mysql, oracle, postgresql
from sqlalchemy import create_engine, MetaData, Column, Boolean
from sqlalchemy.schema import Table

MYSQL = "mysql"
ORACLE = "oracle"
POSTGRES = "postgresql"
SQLITE = "sqlite"

class TINYINT(SmallInteger):
"""The non-standard TINYINT type."""
__visit_name__ = 'TINYINT'


class DOUBLE(Float):
"""The non-standard DOUBLE type."""
__visit_name__ = 'DOUBLE'

@compiles(TINYINT)
def compile_tinyint(type_, compiler, **kw):
return "TINYINT"


@compiles(DOUBLE)
def compile_double(type_, compiler, **kw):
return "DOUBLE"

byte_map = {
MYSQL: mysql.TINYINT(),
ORACLE: oracle.NUMBER(3),
POSTGRES: postgresql.SMALLINT(),
}

double_map = {
MYSQL: mysql.DOUBLE(),
ORACLE: oracle.BINARY_DOUBLE(),
POSTGRES: postgresql.DOUBLE_PRECISION(),
}

def byte(**kwargs):
return _vary(TINYINT(), byte_map, kwargs)


def double(**kwargs):
return _vary(DOUBLE(), double_map, kwargs)

def _vary(type, variant_map, overrides):
for dialect, variant in overrides.items():
variant_map[dialect] = variant
for dialect, variant in variant_map.items():
type.with_variant(variant, dialect)
return type


metadata = MetaData()

t = Table("MyTable", metadata,
  Column("my_byte", byte()),
  Column("my_double", double())
  )


def metadata_dump(sql, *multiparams, **params):
# print or write to log or file etc
print(sql.compile(dialect=engine.dialect))

engine = create_engine("sqlite://", strategy='mock', executor=metadata_dump)
metadata.create_all(engine)


def metadata_dump(sql, *multiparams, **params):
# print or write to log or file etc
print(sql.compile(dialect=engine.dialect))

engine = create_engine("oracle://", strategy='mock', executor=metadata_dump)
metadata.create_all(engine)


-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.