akumoth/peewee-issues huggingface dataset:
Issue: peewee update thrown exception 'UnknownField' object has no attribute 'get_sort_key'
Author: 0xxfu
State: closed
Created: 2019-04-30 02:16:46

code:

```
query = Order.update(is_review=1, review_time=review_time).where(Order.order_sn == order_sn)
query.execute()
```
exception:
```
cursor = database.execute(self)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\peewee.py", line 2952, in execute
    sql, params = ctx.sql(query).query()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\peewee.py", line 601, in sql
    return obj.__sql__(self)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\peewee.py", line 2363, in __sql__
    for k, v in sorted(self._update.items(), key=ctx.column_sort_key):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\peewee.py", line 555, in column_sort_key
    return item[0].get_sort_key(self)
AttributeError: 'UnknownField' object has no attribute 'get_sort_key'
```

environment：
peewee version:3.9.5
python:3.7

You are clearly using models generated using the `pwiz` tool. If pwiz cannot determine the right field type to use for a column, it uses a placeholder "UnknownField". You will need to edit your model definitions and replace the UnknownField with an appropriate field type (e.g. TextField, IntegerField, whatever) if you wish to be able to use it in queries.

> You are clearly using models generated using the `pwiz` tool. If pwiz cannot determine the right field type to use for a column, it uses a placeholder "UnknownField". You will need to edit your model definitions and replace the UnknownField with an appropriate field type (e.g. TextField, IntegerField, whatever) if you wish to be able to use it in queries.

Thanks.
Due to pwiz generate mysql bit field to UnKnownField.
Issue: ValueError: invalid literal for int() with base 10: 'f5W1vg'
Author: mouday
State: closed
Created: 2019-04-28 07:22:42

peewee 2.8.2
python 2.7.5

```python
from playhouse.db_url import connect

db_url = "mysql://root:f5W1vg##123@127.0.0.1:3306/demo"
db = connect(db_url)

```

```
Traceback (most recent call last):
    db = connect(db_url)
  line 85, in connect
    connect_kwargs = parseresult_to_dict(parsed)
  line 49, in parseresult_to_dict
    if parsed.port:
    port = int(port, 10)
ValueError: invalid literal for int() with base 10: 'f5W1vg'
```
maybe password include some not support chart ?


Well, for one, that's quite an old version of Peewee.

The other issue is the use of "#" in the password. Peewee's db_url module uses the stdlib url parsing library, which seems to choke on the "#" in the password for whatever reason.

I'd suggest opening a bug on the Python bug-tracker, if one does not exist.

For Peewee, you'll need to figure out a workaround or just avoid the db_url module in this case.
Issue: Using a BlobField with a context manager results in a AttributeError on 3.9.4
Author: poljar
State: closed
Created: 2019-04-26 16:49:15

The following code snippet results in an AttributeError on 3.9.4, 3.9.3 worked as expected:
```python
from peewee import SqliteDatabase, Model, BlobField

db = SqliteDatabase(":memory:")
class Table(Model):
    field = BlobField()

models = [Table]

with db.bind_ctx(models):
    db.create_tables(models)
```

The following error is thrown after running the code snippet:
```
Traceback (most recent call last):
  File "peewee_fail.py", line 14, in <module>
    db.create_tables(models)
  File "/usr/lib/python3.7/site-packages/peewee.py", line 5829, in __exit__
    model.bind(db, self.bind_refs, self.bind_backrefs)
  File "/usr/lib/python3.7/site-packages/peewee.py", line 6175, in bind
    cls._meta.set_database(database)
  File "/usr/lib/python3.7/site-packages/peewee.py", line 5667, in set_database
    hook(database)
  File "/usr/lib/python3.7/site-packages/peewee.py", line 4422, in _db_hook
    self._constructor = database.get_binary_type()
AttributeError: 'NoneType' object has no attribute 'get_binary_type'
```

The error doesn't happen if we're using a TextField  nor does it happen if we don't use a context manager for the database.

Fixed. Pushing 3.9.5

Thanks for the quick response.
Issue: [Question] Extending Query class to add new query clause
Author: DpodDani
State: closed
Created: 2019-04-20 19:08:37

Hey,

First of all, thank you for creating this wonderful Python database interface API, it has been fun and educating tinkering around in the code base.

This is not really an issue, but more of a question. I am trying to extend Peewee to work with a SQL Server database, however I cannot seem to figure out how to implement a TOP clause - as in `SELECT TOP 10 name from [db].[schema].[table]`. How do you suggest I go about this?

Thank you,
Daniel

Well, the easiest way of course is just to use the `SQL()` helper to insert the sql literal directly (SQL() also supports parameterization):

```python

query = MyModel.select(SQL('TOP 10'))

query = MyModel.select(SQL('TOP %s', (10,)))
```

But more generally to be able to translate a call to `.limit(10)` method, you will probably have a hard time. Unfortunately, at this time, Peewee doesn't provide the level of flexibility in overriding the essentials of the query-building APIs. That's because Model.select delegates to a ModelSelect which extends Select, etc., and it's not straightforward how one would generalize a change to the query building. You could subclass Model and override the select classmethod to provide your own implementation of ModelSelect, of course.

Thank you. I will play around with those suggestions 👍
Issue: Optional Limit after Query Object was Created
Author: r0bc94
State: closed
Created: 2019-04-18 20:45:47

Consider that you have a wrapper method, which obtains a list of all `Entry` objects from a table. 

This method has an optional `limit` parameter that limits the fetched results. If the `limit` parameter is set to -1, all rows should be selected. 

When defining this wrapper function like so:
```Python
def getEntries(limit=-1):
  allEntries = Entry.select()
  
  if limit != -1 and limit >= 0:
    allEntries.limit(limit)

  return list(allEntries)
```

and calling it with `getEntries()` it works fine. However, if I set any value for the `limit` parameter (`getEntries(limit=10)`) the limit is not applied.

Also when looking at the produced query, using `print(allEntries.sql())` before the `return` statement, the `LIMIT` statement is missing. 

My question now is: How can I realize an optional limit parameter without creating a whole new query object? 

With method chaining, we like to act that the queries at each step are immutable, so a copy is returned whenever the query is changed. You just need to reassign:

```python
entries = entries.limit(limit)
```

But your code is gross on just about every possible level for such a short piece of code.

* Default of -1 is gross. It could just as easily be zero, if you take a look at the way you've written your conditional...
* But you don't need to use -1 or 0, just use None
* In fact, you don't even need the condition, because specifying .limit(None) is the same as not specifying any limit
* Why coerce to a list before returning? That forces the query to be evaluated and effectively limits the reuse of that function for any subsequent query-building. Just return the query object -- that way you can apply additional filters/etc if you need to later.

```python
def get_entries(limit=None):
    return Entry.select().limit(limit)
```

Hey, thanks for your reply. 

> But your code is gross on just about every possible level for such a short piece of code.

I would use the excuse, that it was pretty late as I was writing this but I guess I'm just dumb (: 

> But you don't need to use -1 or 0, just use None

I wasn't aware of this. Even if in the documentation, this value default to `None`, I didn't find a hint that if `None` if passed, the query is evaluated without a `Limit`. 

> Why coerce to a list before returning? That forces the query to be evaluated and effectively limits the reuse of that function for any subsequent query-building. Just return the query object -- that way you can apply additional filters/etc if you need to later.

You are having a point here I guess. My thought on this was to wrap all peewee specific calls into a dedicated module and returning pure python objects.

But since the object which is returned from `select()` is iterate-able, there is no need to build a python list from the result.
Issue: [Question] how to insert literal sql fragment to query
Author: james-lawrence
State: closed
Created: 2019-04-16 14:41:49

how does one express:
`SELECT * FROM table WHERE timestamp > '-infinity';`
or
`INSERT INTO table (...., col1) VALUES (....) ON CONFLICT (id) DO UPDATE SET col1 = DEFAULT;`

w/ peewee?

For the first one, depends on the data-type of the timestamp column, the database driver and the db you're using. You can try using `.where(MyModel.timestamp > float('-inf'))` but it may or may not work. A much saner way would be to use `datetime.datetime.min` instead of "-infinity".

For insert / on conflict, there are [extensive docs](http://docs.peewee-orm.com/en/latest/peewee/querying.html#upsert) along with [API documentation](http://docs.peewee-orm.com/en/latest/peewee/api.html#Insert.on_conflict).

To reference the default, you can use `SQL('DEFAULT')`, e.g.:

```python

Table.insert(id=1, col1='foo').on_conflict(
    conflict_target=[Table.id],
    update={Table.col1: SQL('DEFAULT')})
```

Also, please read the documentation. I've clearly requested that, if you have questions, you do not open github issues: http://docs.peewee-orm.com/en/latest/peewee/contributing.html#questions -- stackoverflow, the mailing-list, and the irc channel are all good places to ask questions.

note: i believe peewee.AsIs('-infinity') and peewee.AsIs('DEFAULT') is solving me issue. but I find no reference to the method in the documentation.

That's fine, or `SQL('-infinity')` / `SQL('DEFAULT')` would probably be the more usual way.

I had issues w/ SQL inproperly quoting '-infinity'. that was the first thing I tried. ./shrug.

```
Model.select().where(Model.timestamp > peewee.SQL('-infinity')).execute()
```

fails with `peewee.ProgrammingError: column "infinity" does not exist` because it doesn't quote.
and if you try to force the quotes it starts escaping them (which is fine btw)

```
Model.select().where(Model.created_at > peewee.AsIs('-infinity')).execute()
```
succeeds because it quotes.

the fact AsIs isn't anywhere in the documentation lead to the issue being filed.

> the fact AsIs isn't anywhere in the documentation lead to the issue being filed.

And yet your issue makes no mention of `AsIs` until we get down to the comments.

Did you try `Value('-infinity')` ?
Issue: Add truncate_table back into v3
Author: caidanw
State: closed
Created: 2019-04-12 22:23:40

I would love to see this functionality in v3 as it was available in v2. It doesn't make sense to omit this simple and very useful function. I would prefer to truncate over drop tables when I don't need a table structure change.

I saw your previous comments on a [related issue](https://github.com/coleifer/peewee/issues/1345) but I feel that this still holds value and should be added back into v3.

Is there any specific reason that this shouldn't be added? I can volunteer to port the functionality from v2 -> v3 with documentation and unit tests. Let me know if this is something you're interested in, thanks!

Fixed.

Thank you so much!
Issue: don't release lock when update failed
Author: sison-yuan
State: closed
Created: 2019-04-11 11:21:05

I use mysqldb + peewee, when I update a row to trigger an IntegrityError on an unique key filed, first time, it is normal, but when second, it is in a mysql lock wait until timeout.
when i open the autocommit flag in the mysqldb, the problem is not appear recurrence, I think it is a bug.
i run the mysql 5.7.25 READ-COMMITED , mysql-python 1.2.3
this is my table define
``` sql
CREATE TABLE `groupingKey` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `serviceName` varchar(200) NOT NULL,
  `groupingKey` text NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `groupingKey_serviceName_uindex` (`serviceName`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8
```
my model defind
``` python
class GroupingKey(BaseModel):
    service_name = CharField(column_name='serviceName', unique=True, index=True)
    grouping_key = TextField(column_name='groupingKey')

    class Meta:
        table_name = 'groupingKey'
```

my code:
``` python
        try:
            if grouping_key_id:
                grouping_key_obj = hook_log.query_grouping_key_by_id(grouping_key_id)
                grouping_key_obj.service_name = service_name
                grouping_key_obj.grouping_key = grouping_key
                grouping_key_obj.save()
            else:
                hook_log.create_grouping_key(service_name, grouping_key)
        except IntegrityError:
            # do something
            pass
```


You probably need to run that in a transaction and rollback the transaction in the event an integrity error occurs:

```python
    try:
        with database.atomic():
            if grouping_key_id:
                grouping_key_obj = hook_log.query_grouping_key_by_id(grouping_key_id)
                grouping_key_obj.service_name = service_name
                grouping_key_obj.grouping_key = grouping_key
                grouping_key_obj.save()
            else:
                hook_log.create_grouping_key(service_name, grouping_key)
    except IntegrityError:
        # do something
        pass
```

oh!! I find when I create the Database object, I can set autorollback flag to True, it is useful.

Yes, you can definitely use `autorollback`. This feature was requested by some users and although I do *not* like it, enough people have expressed interest that it is implemented.

I would never use it in my own code. Better to use explicit transactions around data-modifying code (`with db.atomic(): ...`).
Issue: Allow disabling lazy loading - 3.x
Author: brendanblackwood
State: closed
Created: 2019-04-09 18:36:13

I'm upgrading from 2.x to 3.x (finally) and had previously disabled lazy loading of foreign keys via method 2 from #1248. It looks like descriptors have changed/been removed in 3.x. Is there a way to achieve a similar behavior now? Thanks.

Sure - `ForeignKeyField` has an `accessor_class`, which is `ForeignKeyAccessor`. This is a descriptor and it implements a `get_rel_instance()` method, which is what does the actual query for the related obj.

I haven't tested this, but probably something like this ought to work:

```python
class NoQueryForeignKeyAccessor(ForeignKeyAccessor):
    def get_rel_instance(self, instance):
        value = instance.__data__.get(self.name)
        if value is not None:
            if self.name in instance.__rel__:
                return instance.__rel__[self.name]
            else:
                # Ordinarily this would be a query...Instead let's just return the FK col value?
                return value
        elif not self.field.null:
            raise self.rel_model.DoesNotExist

class NoQueryForeignKeyField(ForeignKeyField):
    accessor_class = NoQueryForeignKeyAccessor
```

Makes sense. Thanks!

I've got an implementation in a branch you can check out: https://github.com/coleifer/peewee/tree/feature/disable-fk-lazy-load

It adds an option to `ForeignKeyField`, `lazy_load`, which defaults to True but can be set to False to prevent lazy loading the related model instance.

Perfect! I briefly played with it and that works well.

Merged into master, will be included in the next release.
Issue: Add note to quickstart about deferring database initialization
Author: carlwgeorge
State: closed
Created: 2019-04-06 00:35:18

I'm new to peewee, and must admit I spent way too much time trying to figure out how to make my application use a temporary database during tests.  I'm generating the database path with [appdirs](https://github.com/ActiveState/appdirs) and changing the environment during tests with [pytest's monkeypatch](https://docs.pytest.org/en/latest/reference.html#_pytest.monkeypatch.MonkeyPatch.setenv).  Run-time database configuration was exactly what I needed, I just didn't know to search for that term.  Eventually I found the documentation for that, but I think it's important enough to make note of it in the quickstart.

The quick-start is supposed to be just that -- a quick start. It is nowhere near comprehensive.

The [database](http://docs.peewee-orm.com/en/latest/peewee/database.html) documentation contains tons of information:

* [run-time database configuration](http://docs.peewee-orm.com/en/latest/peewee/database.html#run-time-database-configuration)
* [dynamically defining a database](http://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database)
* [setting the database at run-time](http://docs.peewee-orm.com/en/latest/peewee/database.html#setting-the-database-at-run-time)
* [testing peewee applications](http://docs.peewee-orm.com/en/latest/peewee/database.html#testing)
Issue: regexp not working with database proxy (sqlite)
Author: wice90
State: closed
Created: 2019-04-01 13:58:16

When I try to execute a query with regex (using the regex() method) on a database with proxy I get an error.
This is the table I am operating on:

```from peewee import *
proxy = Proxy()

class BaseModel(Model):
    class Meta:
        database = proxy

class Table2(BaseModel):
    column1= TextField(null=True)
    column2= TextField(null=True)
```

The error:
> Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/peewee.py", line 2875, in execute_sql
    cursor.execute(sql, params or ())
sqlite3.OperationalError: no such function: REGEXP

Printing the .sql() method returns
> ('SELECT "t1"."id", "t1"."column1", "t1"."column2" FROM "TABLE2" AS "t1" WHERE (("t1"."column1" = ?) AND ("t1"."column2" REGEXP ?))', ['app_name_1', '.*'])

I tried to execute the regex method on a database connection without proxy, and it worked as expected. Printing the .sql() method returned different value

> ('SELECT "t1"."id" FROM "TABLE" AS "t1" WHERE ("t1"."name" ~ %s)', ['.* 4'])

PS: I made some changes to peewee.py (in class SqliteDatabase):
- I created a new function:  
 ```
def regexp(self, expr, item):
    reg = re.compile(expr) 
    return reg.search(item) is not None
```  
- Under the function `_connect`, after `sqlite3.connect`, I added the following line:
`conn.create_function("REGEXP", 2, self.regexp)`

After these updates, regex worked on a database accessed via proxy.



How are you initializing your proxy? i.e., what is the database instance you are passing to it to initialize it?

Additionally, Peewee does not automatically register a user-defined regexp implementation for sqlite.

The `playhouse.sqlite_ext.SqliteExtDatabase` *does* allow you to register a REGEXP user-defined function - [documentation](http://docs.peewee-orm.com/en/latest/peewee/sqlite_ext.html#SqliteExtDatabase):

```python
from playhouse.sqlite_ext import SqliteExtDatabase

# Instantiate the sqlite-ext db, and tell it we want to register a regexp function.
db = SqliteExtDatabase('my_database.db', regexp_function=True)
```

Using the standard `peewee.SqliteDatabase` it is also possible to register a user-defined function. You **do not** need to do any crazy shit like hand-editing the code. Here are the docs for registering a user-defined function: http://docs.peewee-orm.com/en/latest/peewee/api.html#SqliteDatabase.func

Example:

```python
db = SqliteDatabase('my_app.db')

@db.func()
def regexp(expr, s):
    return re.search(expr, s) is not None
```

--------

Now, regarding the use of `Proxy` - you cannot register user-defined functions using proxy database, as this is a sqlite-only feature. So you would do something like this:

```python
db = Proxy()

# ... define models, whatever

# Whenever you actually *do* initialize your proxy db, *at that time* you would
# register the user-defined regexp func.
sqlite_db = SqliteDatabase('my_app.db')
db.initialize(sqlite_db)

@db.func()
def regexp(expr, s):
    return re.search(expr, s) is not None
```
Issue: Make sure pwiz take care of camelCase
Author: eggachecat
State: closed
Created: 2019-03-31 11:57:56

Add feature/testcases so that if original table/column name is camelCase the autogenerated one by pwiz will be snake_case


Let's say we have a table named `CamelCaseTableName` who has a column named `camelCase`, with `pwiz`,
## Before
```python
class Camelcasetablename(BaseModel):
    camelcase = CharField(column_name='camelCase')

    class Meta:
        table_name = 'camelCaseTableName'
```

## After
```python
class CamelCaseTableName(BaseModel):
    camel_case = CharField(column_name='camelCase')

    class Meta:
        table_name = 'camelCaseTableName'
```

I appreciate the patch. I've chosen to implement it slightly differently (default to using snake case, more tests, factored table-naming into a function to use in both places it is used).
Issue: Make sure pwiz take care of camelCase
Author: eggachecat
State: closed
Created: 2019-03-31 11:12:14

Add feature/testcases so that if original table/column name is camelCase the autogenerated one by pwiz will be snake_case


Let's say we have a table named `CamelCaseTableName` who has a column named `camelCase`, with `pwiz`,
## Before
```python
class Camelcasetablename(BaseModel):
    camelcase = CharField(column_name='camelCase')

    class Meta:
        table_name = 'camelCaseTableName'
```

## After
```python
class CamelCaseTableName(BaseModel):
    camel_case = CharField(column_name='camelCase')

    class Meta:
        table_name = 'camelCaseTableName'
```

`I will make a new PR since I notice that there's some unnecessary reformatting thanks to pycharm... `
Issue: Use Result from Select Query will create a connection
Author: DoubleX69
State: closed
Created: 2019-03-29 05:46:48

Example:

```python
class User(BaseModel): 
    username = CharField(unique=True)  
    class Meta: 
        db_table = 'user' 

    @classmethod 
    def query_user(cls): 
        with DATABASE.connection_context(): 
            query = User.select() 
        return query 
 
q = User.query_user() 
print(DATABASE.is_closed()) 
for i in q: 
    print(i.username) 
print(DATABASE.is_closed())  ##here will be False 
```



Select queries are lazily evaluated in peewee. How else do you think it would work, given that peewee uses method chaining to build a query?

So when you are building your query -- nothing happens until you:

* iterate over it
* call .get() / .first() / .count() etc on it
* explicitly call .execute()

For your example, you could just coerce to a list if you wanted.