coleifer / peewee

a small, expressive orm -- supports postgresql, mysql, sqlite and cockroachdb
http://docs.peewee-orm.com/
MIT License
11.17k stars 1.37k forks source link

Use "python -m pwiz",the model wrong #2922

Closed Jianan-liu closed 2 months ago

Jianan-liu commented 2 months ago

Peewee version: 3.17.6

image

Jianan-liu commented 2 months ago

single point

petercsiba commented 1 month ago

I have the same problem when the generated code contains single quotes, and is wrapped in single codes yielding to incorrect Python code.

Let me add the simplest example I could to reproduce it:

 sqlite3 example.db << EOM
> create table to_reproduce (problem text not null default 'something in single quotes');
> EOM
python -m pwiz -e sqlite example.db

output:

from peewee import *

database = SqliteDatabase('example.db')

class UnknownField(object):
    def __init__(self, *_, **__): pass

class BaseModel(Model):
    class Meta:
        database = database

class ToReproduce(BaseModel):
    problem = TextField(constraints=[SQL('DEFAULT 'something in single quotes'')])

    class Meta:
        table_name = 'to_reproduce'
        primary_key = False

so the problem is that

problem = TextField(constraints=[SQL('DEFAULT 'something in single quotes'')])

is not a valid Python code.

This is python version 3.9.16 and same peewee==3.17.6;

The weird thing is that this behavior is inconsistent between my python projects (on same Python and Peewee versions). As in my another project I get wrapped this double-quotes:

problem = TextField(constraints=[SQL("DEFAULT 'something in single quotes'")])

I understand the stance of pwiz is

Yes, pwiz is intended to provide a reasonable best-effort at converting the schema into the db into models, but it is not 100% perfect. 

https://github.com/coleifer/peewee/issues/2075#issuecomment-566295451

But I got real curious :D, especially as this should be the code generating it? So I am perplexed how the single quotes happen there

        if self.default is not None:
            params['constraints'] = '[SQL("DEFAULT %s")]' % \
                    self.default.replace('"', '\\"')

https://github.com/coleifer/peewee/blob/6d59dd6c438c2e86ad10e0203e1734e71dfd4e2e/playhouse/reflection.py#L94C1-L97C1

coleifer commented 1 month ago

When I run your example on the latest commit of peewee, I get the following:

class ToReproduce(BaseModel):
    problem = TextField(constraints=[SQL("DEFAULT 'something in single quotes'")])

    class Meta:
        table_name = 'to_reproduce'
        primary_key = False

The fix you referenced is not released yet, but will be included in the next release. Until then you can run against master or a previous tag.

petercsiba commented 1 month ago

@coleifer many thanks! will do your workaround for now