akumoth/peewee-issues huggingface dataset:
Issue: make the build system pep518 compatible
Author: sileht
State: closed
Created: 2022-11-10 13:01:36

Installation of this package is going to break soon.

```
$ pip install peewee
Collecting peewee
  Using cached peewee-3.15.3.tar.gz (858 kB)
  Preparing metadata (setup.py) ... done
Installing collected packages: peewee
  DEPRECATION: peewee is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559
  Running setup.py install for peewee ... done
Successfully installed peewee-3.15.3
```

does the project has planned to upgrade the build system ?

For fucks sake, pypa is so obnoxious! I don't know how to make our setup process compatible with this toml nonsense because we offer several installation modes:

1. When cython is available we will cythonize the extension files
2. When sqlite headers are available we will compile the extensions
3. If sqlite headers are not available we do an installation without the optional extensions.

I think part of the issue is that you don't have the `wheel` package installed, and thus `pip` cannot run `setup.py bdist_wheel`. For some insane reason the pip folks have not found it in their interests to make `wheel` part of either the standard library or the dependencies of `pip` itself, but in the future will effectively treat it as a dependency for projects that don't or can't use "toml".

At any rate, I'm going to hold off on any knee-jerk changes to this library and suggest for now that you install `wheel` first. Going forward, I may need to look into just pushing wheels to pypi, but I don't want to do that because a) concerns about conditionally compiling the extensions, b) cross-platform support for C extensions, and c) breaking everyone's existing installation workflow.

Actually, I'm going to try adding the absolute minimal `pyproject.toml` and see where that gets us.
Issue: NameError: name 'Counter' is not defined in example
Author: stefaneidelloth
State: closed
Created: 2022-11-10 11:56:24

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [7], line 35
     28 users = (User
     29          .select(User, tweet_ct.alias('ct'))
     30          .join(Tweet, JOIN.LEFT_OUTER)
     31          .group_by(User)
     32          .order_by(tweet_ct.desc()))
     34 # Do an atomic update
---> 35 Counter.update(count=Counter.count + 1).where(Counter.url == request.url)

NameError: name 'Counter' is not defined

Yeah the readme is just showing that to illustrate a point. It's hopefully obvious what the intent is.

No, its not. I thought Counter is a missing Class that is also mapped to the database or there is a missing import.
Issue: Bug: ``insert_many`` with tuple insert first character of string 
Author: Sherlock-Homlmes
State: closed
Created: 2022-11-10 09:13:48

**Model:**
```
class Tags(PeeweeModel):
    id = IntegerField()
    name = TextField()

    class Meta:
        db_table = 'tags'
```

**Insert function:**
```
def create_sample_tags():
    list_tags=[
        ('val1-1'),
        ('val2-1'),
        ('val3-1')
    ]
    Tags.insert_many(list_tags, fields=[Tags.name]).execute()
``` 

**Result:**
![image](https://user-images.githubusercontent.com/19506491/201047088-764636b3-9569-43e7-835c-1ec80384b231.png)

It failed to insert the value with tuple.
When I insert_many with dictionary, it still works.

Peewee: 3.15.3
Database: Postgres 15


The thing is `('val1-1')` is not a tuple, it's just a string.

```
>>> v = ('val1-1')
>>> type(v)
<class 'str'>
```

For tuple It shoud be `('val1-1',)`.

This is not a big but you have a mistake in your syntax. @rudyryk has the correct solution.

Also do you really think something THIS foundational would be broken? Next time triple check your own code before creating issues.
Issue: Peewee Not Honouring Alias When Alias Name Matches Column Name
Author: NinjaMeTimbers
State: closed
Created: 2022-11-03 17:49:16

When doing a query with peewee (version 3.14.0), when making an alias for a column that matches the actual column name, the values in the output do not match what was given in the query. It seems to be casting the data to match the data type of the original column. The following code highlights this issue:

```
from peewee import *
db = SqliteDatabase(":memory:")
db.connect()

class A(Model):
	a = BooleanField()
	class Meta:
		database = db

db.create_tables([A])
A.insert(dict(a=True)).execute()
A.insert(dict(a=False)).execute()

print(list(A.select(Case(None, [(A.a, "Y")], "N").alias("a")).dicts()))
print(list(A.select(Case(None, [(A.a, "Y")], "N").alias("b")).dicts()))
```

The output is

```
[{'a': True}, {'a': True}]
[{'b': 'Y'}, {'b': 'N'}]
```

I would expect the output of both cases be the same and to match the output with alias "b".

This is known behavior, as Peewee falls back to using heuristics (column name in this case) to try to determine which "converter" to apply to the value coming back from the database cursor. It is treating each string, 'Y' and 'N' as truth-y boolean values.

To eliminate this behavior, just add `.coerce(False)` to your `Case`:

```python
print(list(A.select(Case(None, [(A.a, "Y")], "N").coerce(False).alias("a")).dicts()))
```

Awesome, thanks!
Issue: Bug: insert_many execute in PostgreSQL returns cursor instead of int row count
Author: bravegag
State: closed
Created: 2022-10-31 15:40:33

Bug: insert_many execute in PostgreSQL returns cursor instead of int row count. In SQLite it returns the int number of rows inserted while in PostgreSQL it returns a cursor.

[In the documentation it states that `insert_many(...).execute()` returns the number of inserted rows.](https://docs.peewee-orm.com/en/latest/peewee/api.html?highlight=insert_many#Model.insert_many)

And if you scrolled further, you'll see: ![screenshot](https://user-images.githubusercontent.com/119974/199052251-48224a6c-cb9c-492e-9102-91894e6deebb.png)

>The default return value is the number of rows modified. However, when using Postgres, Peewee will return a cursor by default that yields the primary-keys of the inserted rows. To disable this functionality with Postgres, use an empty call to returning().

The above will return you the actual psycopg2 cursor.

To get the rowcount instead: https://docs.peewee-orm.com/en/latest/peewee/api.html?highlight=insert_many#Insert.as_rowcount

Ok, thanks! will this same API work with any vendor or is it PostgreSQL specific?


It should work across libraries. Here's a test case if you want to look at some examples:

https://github.com/coleifer/peewee/blob/master/tests/models.py#L419
Issue: API for removing all models Or getting all models
Author: dyadav7
State: closed
Created: 2022-10-31 14:42:51

I want to remove all the models (i.e. remove all tables) without listing all the Model names.
Is there a way to do it ?

OR
I can get all model names using some API and call "drop_tables(models)" also.
Is there an API to get the list of models ? 

e.g.
```
        db.remove all models()
OR
        db.remove all tables()
OR
        models = db.get_models()
        db.drop_tables(models)
```

http://docs.peewee-orm.com/en/latest/peewee/api.html#SubclassAwareMetadata

```python
from peewee import SubclassAwareMetadata

db = SqliteDatabase(':memory:')

class Base(Model):
    class Meta:
        database = db
        model_metadata_class = SubclassAwareMetadata                                     

class P1(Base): pass
class P2(Base): pass
class C1_1(P1): pass
class C1_2(P2): pass

Base._meta.map_models(print)

# Or for you case:
accum = []
Base._meta.map_models(accum.append)
print(accum)
# [<Model: Base>, <Model: P1>, <Model: P2>, <Model: C1_1>, <Model: C1_2>]                  
```

I have removed some Model names form the file. I want to remove all tables names from the db (Includes tables for the Model definition that exist previously).

There is an API to get all table names ( db.get_tables() ).
It return lower case names for Models (e.g. "versiondb" for VersionDB Model).
There should be a way to delete the table names returned by `get_tables()`.

db.remove_tables()  API should be there :
```   
    all_tables = db.get_tables() 
    db.remove__tables(all_tables)
```

@dyadav7 - yes but that does not take into consideration any relationships/dependencies so you'll have to `DROP...CASCADE` all of those presumably. You can just write a loop or your own helper function if you literally want to delete every single table unconditionally:

```python
for table_name in db.get_tables():
    db.execute_sql('drop table if exists "%s" cascade' % table_name)
```

Or drop and re-create your database itself.
Issue: Setting just <fieldtype>(default=None) does not work - but should
Author: MrBillium
State: closed
Created: 2022-10-27 13:16:36

New user here and just ran into this one which surprised me.

Setting a Field default to None does not work by itself when creating  a Model row because there is an implicit null=False.
```
class User(BaseModel):
    name = TextField()
    # last_logged_on = DateTimeField(default=None)  # This will not work when created using default ( i.e. it was omitted)!
    last_logged_on = DateTimeField(null=True, default=None)   # this will work

```

I was  taught that Explicit should ALWAYS override Implicit so I would expect my Field argument (command) to set a field to None to cause Peewee to do everything necessary to make that happen without another argument.

Requiring both is counterintuitive.

Disagree, fields are not-null by default, and there is no "sentinel" value for `default` -- in other words, the default is (by default) None.

All you really need to specify is:

`last_logged_on = DateTimeField(null=True)`
Issue: enhancement for doing get/update/create at the same time
Author: James4Ever0
State: closed
Created: 2022-10-25 09:06:45

here's the following code. it's been tested on some schema with one single unique key.

```python
# peewee.py:7119

    @classmethod
    def get_and_update_or_create(cls, _unique_keys:list=[],**kwargs):
        try:
            obj, flag = cls.get_or_create(
                **kwargs
            )  # will it update this thing? let's see.
        except:
            flag = False
        if not flag:
            fieldNames = [
                name for name, x in cls.__dict__.items() if type(x) == FieldAccessor
            ]
            uniqueKeyNames = _unique_keys
            for name in fieldNames:
                field = cls.__dict__[name].field
                if field.unique:
                    uniqueKeyNames.append(name)
                if field.primary_key:
                    primaryKeyName = name
            # use or/and? better use and.
            uniq_or_primary_key_names_shared_with_kwargs_keys = [
                name
                for name in set([primaryKeyName] + uniqueKeyNames)
                if name in kwargs.keys()
            ]
            # print(dir(cls))
            # print(uniqueKeyNames)
            # print(uniq_or_primary_key_names_shared_with_kwargs_keys)
            # breakpoint()
            operand = None
            for name in uniq_or_primary_key_names_shared_with_kwargs_keys:
                val = cls.__dict__[name].field == kwargs[name]
                if operand is None:
                    operand = val
                else:
                    operand = operand & val
            cls.update(**{key:value for key, value in kwargs.items() if key not in uniq_or_primary_key_names_shared_with_kwargs_keys}).where(
                operand
            ).execute() # damn it.
            # breakpoint() # what is the update result?
            obj= cls.get_or_none(**kwargs) # none?
        return obj, flag

```

Pass

[similar commit](https://github.com/coleifer/peewee/commit/073364ad89a8de48f4a25bbf6106bf42050d34fa)
Issue: Noob question about accesing meta data
Author: ionesculiviucristian
State: closed
Created: 2022-10-24 07:57:08

Hi. I have the following class:

```py
class Migration(BaseModel):
    name = CharField(null=True, unique=True)

    class Meta:
        table_name = "migrations"
```
How can I access the table name without using it like this: 
```py
Migration._meta.table.__name__
```
Need something more "public" kinda way.

> you can modify the source code just like me

Thanks for the response but I have no idea what you are referring to. What source code is that? Worst case I'm gonna add the same ```table_name``` on the parent class which is definitely not the way to do it.

The table name is accessible via:

```
ModelClass._meta.table_name
```

The full list of available meta options is here: http://docs.peewee-orm.com/en/latest/peewee/models.html#model-options-and-table-metadata

The `._meta` is a holdover from Django and is kinda a namespace for metadata of the model class itself. It can be considered part of the public interface.

Note: I've removed a couple comments that were unhelpful or missed the point.
Issue: enhancement to simplify the BaseModel boilerplate code
Author: James4Ever0
State: closed
Created: 2022-10-23 11:10:13

i wrote some code for simplification:

```python

from peewee import *

# some patch on /usr/local/lib/python3.9/dist-packages/peewee.py:3142

# @property
# def Model(self): # this is interesting. does it work as expected?
#     class BaseModel(Model):
#         class Meta:
#             database = self
#     return BaseModel

db = SqliteDatabase('my_database.db')
class User(db.Model):
    username = CharField(unique=True)

```

ps: i've seen this pattern from [sqla-wrapper](https://sqla-wrapper.scaletti.dev/sqlalchemy-wrapper/). this library might be helpful as well.

another enhancement:

```python
# /usr/local/lib/python3.9/dist-packages/peewee.py:3420

#   def create_tables(self, models, bind=True,**options):
#       for model in sort_models(models):
#          if bind:
#              model.bind(self)
#          model.create_table(**options)
class User2(Model):
    username = CharField(unique=True)

db.create_tables([User2])

```

I'm going to pass on the `create_tables()` but have merged the `Model` property helper.
Issue: datetime compare not working correctly with single digit
Author: marcelkb
State: closed
Created: 2022-10-21 20:47:07

MariaDBConnectorDatabase:
DateTimeField:

PriceArchive.select().where(PriceArchive.time <= datetime.datetime(2022, 10, 10, 00, 00)).order_by(
                PriceArchive.time.desc()).limit(1).get()  works correctly

with datetime.datetime(2022, 10, 1, 00, 00) it gives first entry in Database, in my case something from August.

Concrete every day above 9 works, only single digits dates not



seems to be a problem of missing data ;)

I hope it turns up! Sometimes when I lose something, I throw something similar away and watch where it goes.
Issue: Alter column query has wrong syntax
Author: martinzarza
State: closed
Created: 2022-10-20 22:15:25

Hi everyone, I was running an update migration to alter a column type in PostgreSQL, but the query execution fails due to a syntax error.

Here is the migration file:
```python
def migrate(migrator, database, fake=False, **kwargs):
    """Write your migrations here."""

    migrator.change_fields('users', user_id=pw.BigIntegerField(primary_key=True))


def rollback(migrator, database, fake=False, **kwargs):
    """Write your rollback migrations here."""

    migrator.change_fields('users', user_id=pw.IntegerField(primary_key=True))
```

And this is the error message showing the query:
```
Creating migration "migration"
Migration has been created as "002_migration"
Starting migrations
Migrate "002_migration"
change_column ('users', 'user_id', <BigIntegerField: Users.user_id>)
Migration failed: 002_migration
Traceback (most recent call last):
  File "/Users/martin-zarza/Documents/My Projects/sendit-telegram-bot/venv/lib/python3.9/site-packages/peewee.py", line 3221, in execute_sql
    cursor.execute(sql, params or ())
psycopg2.errors.SyntaxError: syntax error at or near "BIGINT"
LINE 1: ALTER TABLE "users" ALTER COLUMN "user_id" BIGINT TYPE PRIMA...
                                                   ^
```

I believe there has to be a *SET* before the *BIGINT...*

`change_fields` is not part of the peewee migration API. Not sure what library you're using but I suggest taking the issue up there.

For what it's worth, the playhouse migrate seems working well (it is not necessary or desirable to include the `primary_key=True` when converting field type - this is preserved):

```python
from playhouse.migrate import *
migrator = SchemaMigrator.from_database(db)

migrate(
    migrator.alter_column_type('users', 'user_id', BigIntegerField())
)
print(db.get_columns('users'))
```

Prints:

```
[ColumnMetadata(
  name='user_id', 
  data_type='bigint', 
  null=False, 
  primary_key=True, 
  table='users', 
  default="nextval('users_user_id_seq'::regclass)"),
 ...
]
```

SQL emitted:

```sql
ALTER TABLE "users" ALTER COLUMN "user_id" TYPE BIGINT
```
Issue: fastapi example is wrong for db connect and close
Author: verigle
State: closed
Created: 2022-10-19 11:15:10

there has wrong example for db connect and close

http://docs.peewee-orm.com/en/latest/peewee/database.html#fastapi

```python
from fastapi import FastAPI
from peewee import *

db = SqliteDatabase('my_app.db')
app = FastAPI()

# This hook ensures that a connection is opened to handle any queries
# generated by the request.
@app.on_event("startup")
def startup():
    db.connect()


# This hook ensures that the connection is closed when we've finished
# processing the request.
@app.on_event("shutdown")
def shutdown():
    if not db.is_closed():
        db.close()
```
however `@app.on_event("startup")` is for application not for request, and `@app.on_event("shutdown")` also for application stop not for request. So those code can not set db connect  before request processing and set db close for request processing over. 


 please reference fastapi document confirm this problem : https://fastapi.tiangolo.com/advanced/events/





peewee document can be reference [this ]( https://fastapi.tiangolo.com/advanced/sql-databases-peewee/#main-fastapi-app
)and then update fastapi example :

```python
    from fastapi import FastAPI
    from peewee import *
   
    import time
    from typing import List
    from fastapi import Depends, FastAPI, HTTPException
    app = FastAPI()
    sleep_time = 10
    db = SqliteDatabase('my_app.db')
    app = FastAPI()
    def get_db():
        try:
            db.connect()
            yield
        finally:
            if not db.is_closed():
                db.close()
    @app.post("/users/", dependencies=[Depends(get_db)])
    def create_user(user):
        pass
```

>So those code can not set db connect before request processing and set db close for request processing over.

Peewee is connection-per-thread. FastAPI does not have such a concept -- rather it has an async context that may be interrupted at any time to switch to another request *within the same thread*. Therefore it's probably better to connect at startup. It's because of subtleties like this, along with the cargo-cult around asyncio, that I advise you to tread carefully.
Issue: Support IN and INNER JOIN subqueries on prefetch
Author: nomme
State: closed
Created: 2022-10-18 11:39:59

This PR intends to solve #2631 

It adds a parameter to `prefetch` that allows the user to choose the type of subquery performed. Using `INNER JOIN` is desirable when combining `LIMIT` with MySQL as the current implementation is not compatible.

Usage example 
```python
from peewee import PREFETCH_TYPE

people = Person.select().order_by(Person.name)
query = people.prefetch(Note, NoteItem, prefetch_type=PREFETCH_TYPE.JOIN)
```

The current behavior should remain the same as `prefetch_type` default to using the current implementation. I suggest whitespace changes are ignored when diffing `prefetch_tests.py`.

It goes without saying, but any feedback is welcome.

Nice patch, thank you. I've rebased your commits into a single commit af3f34f10555a22003726dca90fb2d577617656a and amended it to respect the line-length limit, but otherwise your changes are all merged.
Issue: Support LIMIT with prefetch and MySQL
Author: nomme
State: closed
Created: 2022-10-18 11:33:15

Hi

The premise is simple. It would be pretty sweet if peewee's `prefetch` supports `LIMIT` when using MySQL. I want to add support for it by introducing a switch on `prefetch` that subqueries using `INNER JOIN` instead of `IN`.

Background:
In a project using peewee and MySQL we often encounter the following limitation when using `prefetch`.
```
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
```

This can be seen reported multiple times across the internet, which you also address all those times. [There are ways around it](https://github.com/coleifer/peewee/pull/381#issuecomment-47823210) but native support would feel much better, and would also require one less query and avoid giant `IN` lists with large limit values.

I'll submit a PR in a moment to show what I have in mind.

Merged your PR here: af3f34f10555a22003726dca90fb2d577617656a

Awesome, thank you!
Issue: Unable to install peewee on py 3.10 on windows - ERROR: No .egg-info directory found in C:\Users\*User*\AppData\Local\Temp\pip-pip-egg-info-fhrb40k6
Author: jurezic
State: closed
Created: 2022-10-18 10:42:35

Always getting the same error, except everytime I get another tag in the end of the trace.

Setup-
Python 3.10. 
setuptools-65.5.0
pip-22.3

poetry-
1.1.13.

What I have tried:
Update python/pip/setuptools
Install over poetry - same error

Does anyone have an idea how to proceed?

Can you try doing:

```
git clone https://github.com/coleifer/peewee
cd peewee
python setup.py egg_info
```

And share the output?

Sorry, forgot to mention, I have also downloaded peewee-3.15.3.tar.gz and tried
- py -3.10 -m pip install helpers/peewee-3.15.3.tar.gz
- poetry add helpers/peewee-3.15.3.tar.gz

And again receive -
ERROR: No .egg-info directory found in C:\Users\*user*\AppData\Local\Temp\pip-pip-egg-info-8qd21w02


Can you please try the commands in my comment, and paste the output here?

This is the output of commands from your comment - 

```
'cl.exe' is not recognized as an internal or external command,
operable program or batch file.
unable to compile sqlite3 C extensions - missing headers?
C:\Users\**\Documents\Projects\**\**\helpers\peewee\setup.py:110: UserWarning: Could not find libsqlite3, SQLite extensions will not be built.
  warnings.warn('Could not find libsqlite3, SQLite extensions will not '
running egg_info
creating peewee.egg-info
writing peewee.egg-info\PKG-INFO
writing dependency_links to peewee.egg-info\dependency_links.txt
writing top-level names to peewee.egg-info\top_level.txt
writing manifest file 'peewee.egg-info\SOURCES.txt'
reading manifest file 'peewee.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching 'tests.py'
warning: no files found matching 'playhouse\*.c'
warning: no files found matching 'playhouse\pskel'
warning: no files found matching 'playhouse\tests\README'
adding license file 'LICENSE'
writing manifest file 'peewee.egg-info\SOURCES.txt'
```

Looks like you don't have a C compiler installed (it is not a hard requirement for peewee, but we check), although I'm unsure why `pip` is complaining because the egg-info is successfully written. Anyways, I suggest either:

1. install a c compiler
2. in the `peewee` directory created earlier, just run `python setup.py install` and skip `pip` altogether.