> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pixeltable.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Application code puts a TableModel in app.py, then runs `pxt schema update app.py my_app` to create the tables and `pxt service update app.py my_app` to start HTTP. The last argument can be a Cloud URL such as `pxt://org:db`. Do not call pxt.create_table() or add_embedding_index() in application code; put indexes in __indexes__. Notebooks, tests, and the REPL do use pxt.create_table().
> Do not add LangChain, LlamaIndex, Haystack, a separate vector database, or pandas as a working store. Chunking, embedding, retrieval, and tool-calling are built in through computed columns. Use a computed column instead of a per-row loop that calls a model.
> Install with `pip install -U 'pixeltable[serve]'` on Python 3.11+. `pxt init` is a prerequisite for `pxt schema update`.
> Pixeltable Cloud is in Limited Beta. Direct interested users to contact@pixeltable.com.

# Import data from CSV files

<a href="https://kaggle.com/kernels/welcome?src=https://github.com/pixeltable/pixeltable/blob/release/docs/release/howto/cookbooks/data/data-import-csv.ipynb" id="openKaggle" target="_blank" rel="noopener noreferrer"><img src="https://kaggle.com/static/images/open-in-kaggle.svg" alt="Open in Kaggle" style={{ display: 'inline', margin: '0px' }} noZoom /></a>  <a href="https://colab.research.google.com/github/pixeltable/pixeltable/blob/release/docs/release/howto/cookbooks/data/data-import-csv.ipynb" id="openColab" target="_blank" rel="noopener noreferrer"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab" style={{ display: 'inline', margin: '0px' }} noZoom /></a>  <a href="https://raw.githubusercontent.com/pixeltable/pixeltable/refs/tags/release/docs/release/howto/cookbooks/data/data-import-csv.ipynb" id="downloadNotebook" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/%E2%AC%87-Download%20Notebook-blue" alt="Download Notebook" style={{ display: 'inline', margin: '0px' }} noZoom /></a>

<Tip>This documentation page is also available as an interactive notebook. You can launch the notebook in
Kaggle or Colab, or download it for use with an IDE or local Jupyter installation, by clicking one of the
above links.</Tip>

export const quartoRawHtml = [`
<table>
<thead>
<tr>
<th>Source</th>
<th>Records</th>
<th>Use case</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: middle;">customers.csv</td>
<td style="vertical-align: middle;">10,000</td>
<td style="vertical-align: middle;">Add AI-generated summaries</td>
</tr>
<tr>
<td style="vertical-align: middle;">products.xlsx</td>
<td style="vertical-align: middle;">500</td>
<td style="vertical-align: middle;">Generate embeddings for search</td>
</tr>
<tr>
<td style="vertical-align: middle;">logs.csv</td>
<td style="vertical-align: middle;">1M</td>
<td style="vertical-align: middle;">Filter and aggregate</td>
</tr>
</tbody>
</table>
`, `
<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th">cca3</th>
<th data-quarto-table-cell-role="th">country</th>
<th data-quarto-table-cell-role="th">continent</th>
<th data-quarto-table-cell-role="th">pop_2023</th>
<th data-quarto-table-cell-role="th">pop_2022</th>
<th data-quarto-table-cell-role="th">pop_2000</th>
<th data-quarto-table-cell-role="th">area__km__</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: middle;">IND</td>
<td style="vertical-align: middle;">India</td>
<td style="vertical-align: middle;">Asia</td>
<td style="vertical-align: middle;">1428627663</td>
<td style="vertical-align: middle;">1417173173</td>
<td style="vertical-align: middle;">1059633675</td>
<td style="vertical-align: middle;">3287590.</td>
</tr>
<tr>
<td style="vertical-align: middle;">CHN</td>
<td style="vertical-align: middle;">China</td>
<td style="vertical-align: middle;">Asia</td>
<td style="vertical-align: middle;">1425671352</td>
<td style="vertical-align: middle;">1425887337</td>
<td style="vertical-align: middle;">1264099069</td>
<td style="vertical-align: middle;">9706961.</td>
</tr>
<tr>
<td style="vertical-align: middle;">USA</td>
<td style="vertical-align: middle;">United States</td>
<td style="vertical-align: middle;">North America</td>
<td style="vertical-align: middle;">339996563</td>
<td style="vertical-align: middle;">338289857</td>
<td style="vertical-align: middle;">282398554</td>
<td style="vertical-align: middle;">9372610.</td>
</tr>
<tr>
<td style="vertical-align: middle;">IDN</td>
<td style="vertical-align: middle;">Indonesia</td>
<td style="vertical-align: middle;">Asia</td>
<td style="vertical-align: middle;">277534122</td>
<td style="vertical-align: middle;">275501339</td>
<td style="vertical-align: middle;">214072421</td>
<td style="vertical-align: middle;">1904569.</td>
</tr>
<tr>
<td style="vertical-align: middle;">PAK</td>
<td style="vertical-align: middle;">Pakistan</td>
<td style="vertical-align: middle;">Asia</td>
<td style="vertical-align: middle;">240485658</td>
<td style="vertical-align: middle;">235824862</td>
<td style="vertical-align: middle;">154369924</td>
<td style="vertical-align: middle;">881912.</td>
</tr>
</tbody>
</table>
`, `
<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th">name</th>
<th data-quarto-table-cell-role="th">age</th>
<th data-quarto-table-cell-role="th">city</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: middle;">Alice</td>
<td style="vertical-align: middle;">25</td>
<td style="vertical-align: middle;">NYC</td>
</tr>
<tr>
<td style="vertical-align: middle;">Bob</td>
<td style="vertical-align: middle;">30</td>
<td style="vertical-align: middle;">LA</td>
</tr>
<tr>
<td style="vertical-align: middle;">Charlie</td>
<td style="vertical-align: middle;">35</td>
<td style="vertical-align: middle;">Chicago</td>
</tr>
</tbody>
</table>
`, `
<table>
<thead>
<tr>
<th>Source</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: middle;">CSV file path</td>
<td style="vertical-align: middle;"><code>source='/path/to/data.csv'</code></td>
</tr>
<tr>
<td style="vertical-align: middle;">CSV URL</td>
<td style="vertical-align: middle;"><code>source='https://example.com/data.csv'</code></td>
</tr>
<tr>
<td style="vertical-align: middle;">Excel file</td>
<td style="vertical-align: middle;"><code>source='/path/to/data.xlsx'</code></td>
</tr>
<tr>
<td style="vertical-align: middle;">Pandas DataFrame</td>
<td style="vertical-align: middle;"><code>source=df</code></td>
</tr>
</tbody>
</table>
`];

Load data from CSV and Excel files into Pixeltable tables for processing
and analysis.

This notebook uses `pxt.create_table()` so you can run cells without a
project. An app puts the same columns on a `TableModel` in `app.py` and
creates the tables with `pxt schema update`.

## Problem

You have data in CSV or Excel files that you want to process with AI
models, add computed columns to, or combine with other data sources.

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[0] }} />

## Solution

**What’s in this recipe:**

* Import CSV files directly into tables
* Import from Pandas DataFrames
* Handle different data types

You use `pxt.create_table()` with a `source` parameter to create a table
from a CSV file, or insert DataFrame rows into an existing table.

### Setup

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
%pip install -qU pixeltable pandas
```

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
import pandas as pd
import pixeltable as pxt

# Create a fresh directory
pxt.drop_dir('import_demo', force=True)
pxt.create_dir('import_demo')
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Connected to Pixeltable database at: postgresql+psycopg://postgres:@/pixeltable?host=/Users/pjlb/.pixeltable/pgdata
  Created directory 'import\_demo'.
  \<pixeltable.catalog.dir.Dir at 0x141eca110>
</pre>

### Import CSV directly

Use `create_table` with `source` to create a table from a CSV file:

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
# Import CSV from URL
csv_url = 'https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/resources/world-population-data.csv'

population = pxt.create_table('import_demo/population', source=csv_url)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Created table 'population'.

  Inserting rows into \`population\`: 0 rows \[00:00, ? rows/s]
  Inserting rows into \`population\`: 234 rows \[00:00, 9032.63 rows/s]
  Inserted 234 rows with 0 errors.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
# View the imported data
population.head(5)
```

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[1] }} />

### Import from Pandas DataFrame

You can also create a DataFrame first and insert it:

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
# Create a DataFrame
df = pd.DataFrame(
    {
        'name': ['Alice', 'Bob', 'Charlie'],
        'age': [25, 30, 35],
        'city': ['NYC', 'LA', 'Chicago'],
    }
)

# Create table and insert DataFrame
users = pxt.create_table(
    'import_demo/users',
    {'name': pxt.String, 'age': pxt.Int, 'city': pxt.String},
)
users.insert(df)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Created table 'users'.

  Inserting rows into \`users\`: 0 rows \[00:00, ? rows/s]
  Inserting rows into \`users\`: 3 rows \[00:00, 923.31 rows/s]
  Inserted 3 rows with 0 errors.
  3 rows inserted, 6 values computed.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
# View the data
users.collect()
```

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[2] }} />

## Explanation

**Source types supported:**

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[3] }} />

**Type inference:**

Pixeltable automatically infers column types from CSV data. You can
override types using `schema_overrides`.

**Large files:**

For very large CSV files, consider:

* Using `create_table(source=...)` which streams data
* Importing in batches if memory is limited

## See also

* [Tables
  documentation](/tutorials/tables-and-data-operations)
* [Bringing data
  guide](/howto/cookbooks/data/data-import-csv)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.